質問編集履歴

9

「試したこと(READ COMMITTED)」を追加

2022/08/08 17:11

投稿

nikuatsu
nikuatsu

スコア177

test CHANGED
File without changes
test CHANGED
@@ -210,6 +210,32 @@
210
210
  ### 試したこと(sleep時間の短縮)
211
211
  「質問への追記・修正の依頼」にてmaisumakun様よりご提案頂き`sleep(3)`で試してみたのですが、これも同様のデッドロックでした。
212
212
 
213
+ ### 試したこと(READ COMMITTED)
214
+ [似た状況](https://fukuyama012.hatenablog.com/entry/2018/03/30/191313) を見つけました。いわく、
215
+ > ・SELECTが空振りするとギャップロックになる
216
+ > ・同時に複数のギャップロックが発生するとお互いをブロックしデッドロック状態となる
217
+
218
+ そこで [ギャップロックの回避方法](https://next4us-ti.hatenablog.com/entry/2019/03/26/224404) を見つけ、次のように `// READ COMMITTED に変更` する1行を加えてみました。
219
+
220
+ 結果、デッドロックはなくなりましたが、普通に 'フルーツ4' は重複してしまいました。
221
+ ```php
222
+ function test_insert_on_select_for_update_ver_pdo( $fruits_name, $with_sleep ){
223
+
224
+ $result = ['status'=>'error'];
225
+ try {
226
+
227
+ // DB接続
228
+ $dbh = db_open();
229
+
230
+ // READ COMMITTED に変更
231
+ $dbh->query( "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;" );
232
+
233
+ // トランザクション
234
+ $dbh->beginTransaction();
235
+
236
+ /* 以降は同じ */
237
+ ```
238
+
213
239
  ### ツールのバージョンなど
214
240
  それぞれ次のバージョンです。
215
241
 

8

「試したこと(sleep時間の短縮)」を追記

2022/08/08 13:21

投稿

nikuatsu
nikuatsu

スコア177

test CHANGED
File without changes
test CHANGED
@@ -207,6 +207,9 @@
207
207
  ### 試したこと(ロック状況の確認)
208
208
  コードの過程でロック状況の確認をしようと思いましたが、レンタルサーバーのためその権限がありませんでした。(ユーザーに権限を付与することもできませんでした。)
209
209
 
210
+ ### 試したこと(sleep時間の短縮)
211
+ 「質問への追記・修正の依頼」にてmaisumakun様よりご提案頂き`sleep(3)`で試してみたのですが、これも同様のデッドロックでした。
212
+
210
213
  ### ツールのバージョンなど
211
214
  それぞれ次のバージョンです。
212
215
 

7

試したこと(ロック状況の確認)を追記

2022/08/07 20:24

投稿

nikuatsu
nikuatsu

スコア177

test CHANGED
File without changes
test CHANGED
@@ -204,6 +204,9 @@
204
204
  しかし削除してしまうと検索に不向きなので、これを解決策として採用したくはありません。
205
205
  そしてフルテキストインデックスですと検索に数秒かかるので、通常のインデックスを使いたいです。
206
206
 
207
+ ### 試したこと(ロック状況の確認)
208
+ コードの過程でロック状況の確認をしようと思いましたが、レンタルサーバーのためその権限がありませんでした。(ユーザーに権限を付与することもできませんでした。)
209
+
207
210
  ### ツールのバージョンなど
208
211
  それぞれ次のバージョンです。
209
212
 

6

加筆

2022/08/07 20:21

投稿

nikuatsu
nikuatsu

スコア177

test CHANGED
File without changes
test CHANGED
@@ -58,7 +58,9 @@
58
58
 
59
59
  ### 実現したいこと
60
60
  該当のソースコードの実行に際して`fruits_name`の重複を避けたいです。
61
+
61
62
  そしてデッドロックの原因と解決策を知りたいです。
63
+ (特に、なぜインデックスを貼ることでデッドロックが起こるのか?が大いに疑問です。)
62
64
 
63
65
  ### 発生している問題・エラーメッセージ
64
66
  1回目に該当のソースコードを実行すると、`var_dump($result);` は次の結果を出力します。

5

一部加筆

2022/08/07 20:12

投稿

nikuatsu
nikuatsu

スコア177

test CHANGED
File without changes
test CHANGED
@@ -58,6 +58,7 @@
58
58
 
59
59
  ### 実現したいこと
60
60
  該当のソースコードの実行に際して`fruits_name`の重複を避けたいです。
61
+ そしてデッドロックの原因と解決策を知りたいです。
61
62
 
62
63
  ### 発生している問題・エラーメッセージ
63
64
  1回目に該当のソースコードを実行すると、`var_dump($result);` は次の結果を出力します。
@@ -171,9 +172,9 @@
171
172
  ```
172
173
 
173
174
  ### 試したこと(テーブルロック)
174
- `beginTransaction``SELECT...FOR UPDATE`でなく`LOCK TABLES`を利用すると1回目も2回目もデッドロックは起こらず、次のように2回目を`exists`にできました。
175
+ `beginTransaction``SELECT...FOR UPDATE`でなく`LOCK TABLES`と`SELECT`」を利用すると1回目も2回目もデッドロックは起こらず、次のように2回目を`exists`にできました。
175
-
176
+
176
- しかしテーブルロックしてしまうと閲覧もできないので、これを解決策として採用したくはありません。
177
+ しかしテーブルロックしてしまうと閲覧もできませんし他待ちも生じてしまうので、これを解決策として採用したくはありません。
177
178
 
178
179
  1回目
179
180
  ```php
@@ -210,4 +211,4 @@
210
211
  宜しくお願い致します。
211
212
 
212
213
  ### 補足
213
- 該当のソースコードはフルーツのみの内容になっていますが、実際にはフルーツとタグの投稿も想定されます。そのため一方が失敗した場合に備えてロールバックを可能にしたく、その意味で`beginTransaction`は必須と考えています。
214
+ 該当のソースコードはフルーツのみの内容になっていますが、実際にはフルーツとタグの投稿も想定されます。そのため一方が失敗した場合に備えてロールバックを可能にしたく、その意味で`beginTransaction`は必須と考えています。

4

誤字

2022/08/07 20:09

投稿

nikuatsu
nikuatsu

スコア177

test CHANGED
File without changes
test CHANGED
@@ -210,4 +210,4 @@
210
210
  宜しくお願い致します。
211
211
 
212
212
  ### 補足
213
- 該当のソースコードはフルーツのみの内容になっていますが、実際にはフルーツとタグの投稿も想定されます。そのため一方が失敗した場合に備えてロールバックを可能にしく、その意味で`beginTransaction`は必須と考えています。
213
+ 該当のソースコードはフルーツのみの内容になっていますが、実際にはフルーツとタグの投稿も想定されます。そのため一方が失敗した場合に備えてロールバックを可能にしく、その意味で`beginTransaction`は必須と考えています。

3

補足

2022/08/07 20:08

投稿

nikuatsu
nikuatsu

スコア177

test CHANGED
File without changes
test CHANGED
@@ -209,3 +209,5 @@
209
209
 
210
210
  宜しくお願い致します。
211
211
 
212
+ ### 補足
213
+ 該当のソースコードはフルーツのみの内容になっていますが、実際にはフルーツとタグの投稿も想定されます。そのため一方が失敗した場合に備えてロールバックを可能にしく、その意味で`beginTransaction`は必須と考えています。

2

試したことを一部加筆

2022/08/07 18:52

投稿

nikuatsu
nikuatsu

スコア177

test CHANGED
File without changes
test CHANGED
@@ -171,7 +171,7 @@
171
171
  ```
172
172
 
173
173
  ### 試したこと(テーブルロック)
174
- `beginTransaction`でなく`LOCK TABLES`を利用すると1回目も2回目もデッドロックは起こらず、次のように2回目を`exists`にできました。
174
+ `beginTransaction`や`SELECT...FOR UPDATE`でなく`LOCK TABLES`を利用すると1回目も2回目もデッドロックは起こらず、次のように2回目を`exists`にできました。
175
175
 
176
176
  しかしテーブルロックしてしまうと閲覧もできないので、これを解決策として採用したくはありません。
177
177
 

1

誤字

2022/08/07 18:51

投稿

nikuatsu
nikuatsu

スコア177

test CHANGED
File without changes
test CHANGED
@@ -170,10 +170,10 @@
170
170
 
171
171
  ```
172
172
 
173
- ### 試したこと(テーブロック)
173
+ ### 試したこと(テーブロック)
174
174
  `beginTransaction`でなく`LOCK TABLES`を利用すると1回目も2回目もデッドロックは起こらず、次のように2回目を`exists`にできました。
175
175
 
176
- しかしテーブロックしてしまうと閲覧もできないので、これを解決策として採用したくはありません。
176
+ しかしテーブロックしてしまうと閲覧もできないので、これを解決策として採用したくはありません。
177
177
 
178
178
  1回目
179
179
  ```php
@@ -196,7 +196,7 @@
196
196
  ```
197
197
 
198
198
  ### 試したこと(インデックス削除)
199
- なぜか`fruits_name`のインデックスを削除したところ、上記テーブロックした場合と同様に解決が見られました。
199
+ なぜか`fruits_name`のインデックスを削除したところ、上記テーブロックした場合と同様に解決が見られました。
200
200
 
201
201
  しかし削除してしまうと検索に不向きなので、これを解決策として採用したくはありません。
202
202
  そしてフルテキストインデックスですと検索に数秒かかるので、通常のインデックスを使いたいです。