"チケット"テーブルからUIDを生成するストアドプロシージャがありますが、負荷がかかってデッドロックが多く発生しています。自分のタスクが新しいUIDを必要とするときは、このプロシージャを複数の同時接続から何度も呼び出すことにします。ストアドプロシージャでUIDを生成するデッドロック
BEGIN
DECLARE a_uid BIGINT(20) UNSIGNED;
START TRANSACTION;
SELECT uid INTO a_uid FROM uid_data FOR UPDATE; # Lock
INSERT INTO uid_data (stub) VALUES ('a') ON DUPLICATE KEY UPDATE uid=uid+1;
SELECT a_uid+1 AS `uid`;
COMMIT;
END
私が使用して検討しました:SELECT FOR UPDATE
との最初の手順とは異なり、ロックがないように、その同時接続で安全であるかどう
BEGIN
REPLACE INTO uid_data (stub) VALUES ('a');
SELECT LAST_INSERT_ID();
END
は、しかし、私は確認されませんでした。ここで
はテーブルです:
mysql> DESCRIBE uid_data;
+-------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+----------------+
| uid | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| stub | char(1) | NO | UNI | NULL | |
+-------+---------------------+------+-----+---------+----------------+
Iは、読み取りコミットトランザクション分離のためにセットアップしました:ここで私は、私は戻ってSHOW ENGINE INNODB STATUS;
...
... dozens and dozens of the following record locks...
Record lock, heap no 1046 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 1; hex 61; asc a;;
1: len 8; hex 00000000000335f2; asc 5 ;;
Record lock, heap no 1047 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 1; hex 61; asc a;;
1: len 8; hex 00000000000335f1; asc 5 ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 13 page no 4 n bits 1120 index `stub` of table `my_db`.`uid_data` trx id 13AA89 lock_mode X waiting
Record lock, heap no 583 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 1; hex 61; asc a;;
1: len 8; hex 00000000000334a8; asc 4 ;;
*** WE ROLL BACK TRANSACTION (1)
から取得しています何
mysql> SHOW VARIABLES LIKE 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | READ-COMMITTED |
+---------------+-----------------+
です誰かが何が起こっているのか、どのように回避できるのかを説明できると感謝しています。
トランザクション1:デッドロックがこの状況で発生し
詳細については、この単純なシーケンスを使用している場合でもデッドロックが発生します: 'START TRANSACTION; uid_dataからFROM uidを選択してください。 UPDATE uid_data SET uid = uid +1 [[ここでデッドロックが発生する可能性があります]]; COMMIT; '(したがって、' ON DUPLICATE'節とは関係ありません)。ただし、分離レベルが 'REPEATABLE READ;'でデッドロックは発生しません。私はまだこの点から何を結論するか分からない。 – RandomSeed