sql 死锁

先上代码connectA:

BEGIN TRAN

UPDATE dbo.Student SET Sorce=89 WHERE id=5
waitfor delay '00:00:05'
SELECT * FROM dbo.Teacher WHERE id=1

COMMIT TRAN

connectB:

BEGIN TRAN

UPDATE dbo.Teacher SET Age=21 WHERE Id=1
SELECT * FROM dbo.Student WHERE Id=5

COMMIT TRAN

A的操作:开启事物=》更新表student=》等待5s=》查询表teacher=》提交事物

B的操作:开启事物=》更新表teacher=》查询表student=》提交事物

结果B的操作出现:

Msg 1205, Level 13, State 51, Line 4
Transaction (Process ID 59) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

意思为:出现死锁,B的连接事务回滚

分析:

现在事务的隔离级别为默认的 READ COMMITTED,该级别排他锁和共享锁是不能同时的。

1.当A连接先执行的时候,更新student表,student表会加一个排他锁,等待5秒。

2.此时执行B的操作,更新teacher表,teacher表会加一个排他锁。然后执行查询表student,查询是添加一个共享锁,但student表已经添加了排他锁,只有等待排他锁的释放。

3.A操作的5s等待完成,执行查询teacher表,teacher表在B连接已经加了排他锁,只能等待teacher表排他锁的释放。

4.这个时候就造成了死锁。

5.系统发现死锁后,会根据配置和系统开销估算。哪个事物回滚,哪个提交。

解决方案:

1.降低事物的隔离等级,一般不用。

2.将与业务逻辑无关的查询放到事物外。

3.在事物中表的操作顺序调整为一致。例如B连接改为:

BEGIN TRAN

SELECT * FROM dbo.Student WHERE Id=5
UPDATE dbo.Teacher SET Age=22 WHERE Id=1

COMMIT TRAN

猜你喜欢

转载自www.cnblogs.com/zhuyapeng/p/9436128.html