先上代碼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