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 ,這樣的並發也會死鎖嗎?