死锁,简而言之,两个或者多个trans,同时请求对方正在请求的某个对象,导致双方互相等待。简单的例子如下:
trans1 trans2
------------------------------------------------------------------------
1.IDBConnection.BeginTransaction 1.IDBConnection.BeginTransaction
2.update table A 2.update table B
3.update table B 3.update table A
4.IDBConnection.Commit 4.IDBConnection.Commit
trans1 trans2
------------------------------------------------------------------------
1.IDBConnection.BeginTransaction 1.IDBConnection.BeginTransaction
2.update table A 2.update table B
3.update table B 3.update table A
4.IDBConnection.Commit 4.IDBConnection.Commit
那么,很容易看到,如果trans1和trans2,分别到达了step3,那么trans1会请求对于B的X锁,trans2会请求对于A的X锁,而二者的锁在step2上已经被对方分别持有了。由于得不到锁,后面的Commit无法执行,这样双方开始死锁。
举个例子:创建一张表
create table test
(
a varchar(30),
b varchar(30)
)
模拟两个用户操作:
用户1:
begin tran
insert test values('aa','bb')
用户2:
begin tran
select * from test
先执行用户1,则用户2在用户1未执行commit tran 之前就无法执行。
因为事务1对test加了锁,事务2无法对加锁对象test操作。
两种解决办法:
1.commit tran
2.在事务2里加上
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED