MySQL死锁案例

it2022-05-05  175

 

死锁案例1

多线程以不同顺序对相同资源加锁导致死锁。

时间

会话A

会话B

1BEGIN; 2SELECT * FROM t WHERE a = 1 FOR UPDATE;BEGIN;3 SELECT * FROM t WHERE a = 2 FOR UPDATE;4

SELECT * FROM t WHERE a = 2 FOR UPDATE;

-- 开始等待B释放锁

 5 

SELECT * FROM t WHERE a = 1 FOR UPDATE;

-- 等待A释放锁,产生死锁

 

解决方案:

1.可以在业务层面上保证加锁的顺序一致;

2.大事务拆分成小事务。

 

死锁案例2

S锁X锁的陷阱。

时间

会话A

会话B

1BEGIN; 2

INSERT INTO test_copy SELECT * FROM test WHERE id =8;

-- 对test表中id = 8的记录加S锁,等同于

SELECT * FROM test WHERE id = 8 LOCK IN SHARE MODE;

BEGIN;3 

SELECT * FROM test WHERE id = 8 FOR UPDATE;

-- 申请对id = 8的记录加X锁,开始等待

4

SELECT * FROM test WHERE id = 8 FOR UPDATE;

-- 申请对资源加X锁,发现已经被B锁定,等待B释放X锁,产生死锁

 

解决方案:

将会话A中加的S锁改成X锁:INSERT INTO test_copy SELECT * FROM test WHERE id =8 FOR UPDATE;

保证会话A结束前,会话B不会对资源加X锁。


最新回复(0)