Cái gì hiệu quả và cái gì không
Một cách để làm cho cả hai giao dịch chạy qua mà không gặp bế tắc là thay đổi mức cô lập để ĐỌC ĐƯỢC CAM KẾT (hoặc ĐỌC KHÔNG ĐƯỢC ĐỀ XUẤT ) trong cả hai kết nối:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
(trước khi start transaction
).
Có thể là đủ để đặt nó trong t2
, nhưng chỉ để chắc chắn cho ví dụ, hãy đặt nó ở cả hai.
Việc thay đổi mức độ cô lập của các giao dịch sẽ dẫn đến một số tác dụng phụ, mà tác dụng phụ nên thông báo về trong hướng dẫn sử dụng trước khi thay đổi điều này trong môi trường sản xuất.
Thông tin trạng thái liên quan đến bế tắc
------------------------
LATEST DETECTED DEADLOCK
------------------------
140424 8:45:46
*** (1) TRANSACTION:
TRANSACTION B6F18A3, ACTIVE 5 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s)
MySQL thread id 13885, OS thread handle 0x7f8b1dbd2700, query id 901012
localhost root statistics
SELECT * FROM t WHERE id = 1 FOR UPDATE
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 22921 n bits 72 index `PRIMARY` of table
`test`.`t` trx id B6F18A3 lock_mode X locks rec but not gap waiting
Record lock, heap no 4 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 80000001; asc ;;
1: len 6; hex 00000b6f1883; asc o ;;
2: len 7; hex 06000059a211ea; asc Y ;;
3: len 5; hex 48656c6c6f; asc Hello;;
*** (2) TRANSACTION:
TRANSACTION B6F18A2, ACTIVE 10 sec starting index read
mysql tables in use 1, locked 1
3 lock struct(s), heap size 376, 2 row lock(s)
MySQL thread id 13888, OS thread handle 0x7f8b1f64d700, query id 901068
localhost root Updating
UPDATE t SET `descc` = 'Hello from t1'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 22921 n bits 72 index `PRIMARY` of table
`test`.`t` trx id B6F18A2 lock_mode X locks rec but not gap
Record lock, heap no 4 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 80000001; asc ;;
1: len 6; hex 00000b6f1883; asc o ;;
2: len 7; hex 06000059a211ea; asc Y ;;
3: len 5; hex 48656c6c6f; asc Hello;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 22921 n bits 72 index `PRIMARY` of table
`test`.`t` trx id B6F18A2 lock_mode X waiting
Record lock, heap no 4 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 80000001; asc ;;
1: len 6; hex 00000b6f1883; asc o ;;
2: len 7; hex 06000059a211ea; asc Y ;;
3: len 5; hex 48656c6c6f; asc Hello;;
*** WE ROLL BACK TRANSACTION (1)
Giải thích
Như a_horse_with_no_name đã đề cập, đây có vẻ như là một lỗi trong MySQL. Giao dịch (2) muốn có được một khóa khoảng trống trên cùng một hàng, nó đã giữ một khóa X. Giao dịch (1) chờ khóa X không có khoảng cách trên hàng này. Tôi không rõ tại sao yêu cầu này lại xung đột. Đặt mức cô lập thành READ COMMITTED
vô hiệu hóa khóa khoảng cách. Vì ví dụ hoạt động sau đó, đây là một gợi ý rằng khóa khoảng cách thực sự là vấn đề ở đây.