Tôi có một thủ tục lưu trữ tạo ra UID từ một bảng "vé", nhưng dưới tải tôi nhận được rất nhiều deadlocks. Tôi đang gọi thủ tục này nhiều lần từ nhiều kết nối đồng thời bất cứ khi nào nhiệm vụ của tôi cần một UID mới.MySQL deadlocks với thủ tục lưu trữ tạo ra 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
tôi đã xem xét sử dụng:
BEGIN
REPLACE INTO uid_data (stub) VALUES ('a');
SELECT LAST_INSERT_ID();
END
Tuy nhiên tôi không chắc rằng sẽ được an toàn với kết nối đồng thời là không có khóa, không giống như các thủ tục đầu tiên với SELECT FOR UPDATE
.
Dưới đây là bảng:
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 | |
+-------+---------------------+------+-----+---------+----------------+
tôi đã thiết lập cho cô lập giao dịch đọc cam kết:
mysql> SHOW VARIABLES LIKE 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | READ-COMMITTED |
+---------------+-----------------+
Đây là những gì tôi nhận được lại từ 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)
tôi Tôi rất biết ơn nếu ai đó có thể giải thích những gì đang xảy ra và cách họ có thể tránh được.
Để biết thông tin: bế tắc xảy ra ngay cả khi sử dụng trình tự đơn giản này: 'BẮT ĐẦU GIAO DỊCH; CHỌN uid TỪ uid_data CHO CẬP NHẬT; CẬP NHẬT uid_data SET uid = uid +1 [[deadlock có thể ở đây]]; COMMIT; '(do đó nó không liên quan gì đến mệnh đề' ON DUPLICATE'). Tuy nhiên, không có bế tắc nào xảy ra với mức cô lập 'REPEATABLE READ;'. Tôi vẫn không biết phải kết luận gì từ thời điểm này. – RandomSeed