SQL Server 2008 R2 太容易出现死锁了,无语了。
做了个简单例子测试一下:
1.建一个测试表:
CREATE
TABLE
[
dbo
].
[
LockTest
](
[ ID ] [ int ] NULL,
[ Name ] [ nvarchar ]( 10) NULL
) ON [ PRIMARY ]
GO
[ ID ] [ int ] NULL,
[ Name ] [ nvarchar ]( 10) NULL
) ON [ PRIMARY ]
GO
随便插入2条记录,然后,打开SSMS,新建2个查询,同时执行下面的代码,模拟2个并发线程更新同一张表,不同记录的情况:
set
transaction
isolation
level
serializable
declare @count int
declare @tranname varchar( 10)
set @count = 1
while( @count < 10)
begin
set @tranname = ' B ' + convert( varchar, @count)
begin tran @tranname
update dbo.LockTest set Name = ' BBBB ' where ID = 2;
waitfor delay ' 00:00:02 '
commit tran @tranname
set @count = @count + 1
end
declare @count int
declare @tranname varchar( 10)
set @count = 1
while( @count < 10)
begin
set @tranname = ' B ' + convert( varchar, @count)
begin tran @tranname
update dbo.LockTest set Name = ' BBBB ' where ID = 2;
waitfor delay ' 00:00:02 '
commit tran @tranname
set @count = @count + 1
end
set
transaction
isolation
level
serializable
declare @count int
declare @tranname varchar( 10)
set @count = 1
while( @count < 10)
begin
set @tranname = ' A ' + convert( varchar, @count)
begin tran @tranname
update dbo.LockTest set Name = ' aaa ' where ID = 1
waitfor delay ' 00:00:02 '
commit tran @tranname
set @count = @count + 1
end
declare @count int
declare @tranname varchar( 10)
set @count = 1
while( @count < 10)
begin
set @tranname = ' A ' + convert( varchar, @count)
begin tran @tranname
update dbo.LockTest set Name = ' aaa ' where ID = 1
waitfor delay ' 00:00:02 '
commit tran @tranname
set @count = @count + 1
end
按道理,这不应该造成死锁,顶多互相阻塞一下而已,但事实上,确引发了死锁。
(1 行受影响)
commit tran :A1
begin tran :A2
消息 1205,级别 13,状态 18,第 10 行
事务(进程 ID 56)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。
查看后台日志,发现如下:
说明,2个进程都申请到了IX锁,然后其中一个要将IX转成X锁,转换失败,造成死锁。
我的疑问是,难道SQL Server ,这样的并发也会死锁吗?