MySQL InnoDB は影響を受ける行のみをロックしますか?
-
22-09-2019 - |
質問
次のようなユーザーを含む InnoDB テーブルがあります。
+--------------+-----------------------+
| user_id | name |
+--------------+-----------------------+
| 1 | Bob |
| 1 | Marry |
| 2 | Bob |
| 1 | John |
| 3 | Bob |
| 2 | Marry |
+--------------+-----------------------+
挿入するたびに user_id を 1 ずつ増やすので、たとえば、Bob の次の user_id は 4 になります。
これを行うには次のクエリを使用します。
INSERT INTO users (user_id, name)
SELECT 1 + coalesce((SELECT max(user_id) FROM users WHERE name='Bob'), 0), 'Bob';
次に、2 人の異なるユーザーが同時に「Bob」を追加しないようにする必要があります。user_id 4 の Bob は 2 つも必要ありません。ボブの各ユーザー ID は異なる必要があります。
上記の挿入クエリを実行したときに、Bob のすべての行をロックして書き込みおよび更新することは可能ですか?他の多くのユーザーがまだ自分の行への完全なアクセスを必要としているため、テーブル全体をロックすることはできません。また、すべての行が常に読み取り可能である必要があります。どうすればいいでしょうか?
解決
ここにはInnoDBと仮定すると、あなたは SELECTを使用することができます。 ... LOCKを共有MODEは、あなたがそれらを選択すると、行をロックするを。
他のヒント
は、あなたの質問の最初の部分を解決するために、 USER_IDと名前のユニーク索引を作成します。
alter table `users` add unique index ak_user_id_name(user_id,name);
これは重複のuser_id、名前レコードを防止します。
この質問に対する答えは次と同じです これです. 。InnoDB は、ステートメントベースのバイナリ ログの安全性を確保するために、ここで予想よりも多くの行をロックします。
ソリューション: 読み取りコミット分離レベルで行ベースのバイナリ ロギングを使用します。
所属していません StackOverflow