SQL的死锁
时间:2010-06-10 来源:如戏
转载自: CSDN
http://topic.csdn.net/u/20080721/20/15a60db6-34b5-4ea1-b392-11c42270aaab.html
--死鎖
/******************************************************************************************************************************************************
死鎖指兩個以上事務相互阻塞相互等待對方釋放它們的鎖,SQL Server會通過回滾其中一個事務並返回一個錯誤來自已解決阻塞問題,讓其他事務完成它們的工作。
整理人:中国风(Roy)
日期:2008.07.20
******************************************************************************************************************************************************/
set nocount on ;
if object_id('T1') is not null
drop table T1
go
create table T1(ID int primary key,Col1 int,Col2 nvarchar(20))
insert T1 select 1,101,'A'
insert T1 select 2,102,'B'
insert T1 select 3,103,'C'
go
if object_id('T2') is not null
drop table T2
go
create table T2(ID int primary key,Col1 int,Col2 nvarchar(20))
insert T2 select 1,201,'X'
insert T2 select 2,202,'Y'
insert T2 select 3,203,'Z'
go
生成表數據:
/*
T1:
ID Col1 Col2
----------- ----------- --------------------
1 101 A
2 101 B
3 101 C
T2:
ID Col1 Col2
----------- ----------- --------------------
1 201 X
2 201 Y
3 201 Z
*/
防止死鎖:
1、 最少化阻塞。阻塞越少,發生死鎖機會越少
2、 在事務中按順序訪問表(以上例子:死鎖2)
3、 在錯誤處理程式中檢查錯誤1205並在錯誤發生時重新提交事務
4、 在錯誤處理程式中加一個過程將錯誤的詳細寫入日誌
5、 索引的合理使用(以上例子:死鎖1、死鎖3)
當發生死鎖時,事務自動提交,可通過日誌來監視死鎖
死鎖1(索引):
--連接窗口1
--1步:
begin tran
update t1 set col2=col2+'A' where col1=101
--3步:
select * from t2 where col1=201
commit tran
--連接窗口2
--2步:
begin tran
update t2 set col2=col2+'B' where col1=203
--4步:
select * from t1 where col1=103
commit tran
--連接窗口1:收到死鎖錯誤,連接窗口2得到結果:
/*
訊息 1205,層級 13,狀態 51,行 3
交易 (處理序識別碼 53) 在 鎖定 資源上被另一個處理序鎖死並已被選擇作為死結的犧牲者。請重新執行該交易。
*/
--連接窗口2:得到結果
/*
----------- ----------- --------------------
3 103 C
*/
死鎖指兩個以上事務相互阻塞相互等待對方釋放它們的鎖,SQL Server會通過回滾其中一個事務並返回一個錯誤來自已解決阻塞問題,讓其他事務完成它們的工作。
整理人:中国风(Roy)
日期:2008.07.20
******************************************************************************************************************************************************/
set nocount on ;
if object_id('T1') is not null
drop table T1
go
create table T1(ID int primary key,Col1 int,Col2 nvarchar(20))
insert T1 select 1,101,'A'
insert T1 select 2,102,'B'
insert T1 select 3,103,'C'
go
if object_id('T2') is not null
drop table T2
go
create table T2(ID int primary key,Col1 int,Col2 nvarchar(20))
insert T2 select 1,201,'X'
insert T2 select 2,202,'Y'
insert T2 select 3,203,'Z'
go
生成表數據:
/*
T1:
ID Col1 Col2
----------- ----------- --------------------
1 101 A
2 101 B
3 101 C
T2:
ID Col1 Col2
----------- ----------- --------------------
1 201 X
2 201 Y
3 201 Z
*/
防止死鎖:
1、 最少化阻塞。阻塞越少,發生死鎖機會越少
2、 在事務中按順序訪問表(以上例子:死鎖2)
3、 在錯誤處理程式中檢查錯誤1205並在錯誤發生時重新提交事務
4、 在錯誤處理程式中加一個過程將錯誤的詳細寫入日誌
5、 索引的合理使用(以上例子:死鎖1、死鎖3)
當發生死鎖時,事務自動提交,可通過日誌來監視死鎖
死鎖1(索引):
--連接窗口1
--1步:
begin tran
update t1 set col2=col2+'A' where col1=101
--3步:
select * from t2 where col1=201
commit tran
--連接窗口2
--2步:
begin tran
update t2 set col2=col2+'B' where col1=203
--4步:
select * from t1 where col1=103
commit tran
--連接窗口1:收到死鎖錯誤,連接窗口2得到結果:
/*
訊息 1205,層級 13,狀態 51,行 3
交易 (處理序識別碼 53) 在 鎖定 資源上被另一個處理序鎖死並已被選擇作為死結的犧牲者。請重新執行該交易。
*/
--連接窗口2:得到結果
/*
----------- ----------- --------------------
3 103 C
*/
相关阅读 更多 +