您好,欢迎来到思海网络,我们将竭诚为您提供优质的服务! 诚征网络推广 | 网站备案 | 帮助中心 | 软件下载 | 购买流程 | 付款方式 | 联系我们 [ 会员登录/注册 ]
促销推广
客服中心
业务咨询
有事点击这里…  531199185
有事点击这里…  61352289
点击这里给我发消息  81721488
有事点击这里…  376585780
有事点击这里…  872642803
有事点击这里…  459248018
有事点击这里…  61352288
有事点击这里…  380791050
技术支持
有事点击这里…  714236853
有事点击这里…  719304487
有事点击这里…  1208894568
有事点击这里…  61352289
在线客服
有事点击这里…  531199185
有事点击这里…  61352288
有事点击这里…  983054746
有事点击这里…  893984210
当前位置:首页 >> 技术文章 >> 文章浏览
技术文章

在SQL Server 2005中解决死锁

添加时间:2014-10-23 1:53:27  添加: 思海网络 

数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过SQL Server 2005, 现在似乎有了一种新的解决办法。

将下面的SQL语句放在两个不同的连接里面,并且在5秒内同时执行,将会发生死锁。


use Northwind

begin tran 
    insert into Orders(CustomerId) values('ALFKI') 
    waitfor delay '00:00:05' 
    select * from Orders where CustomerId = 'ALFKI' 
commit 
print 'end tran' 
SQL Server对付死锁的办法是牺牲掉其中的一个,抛出异常,并且回滚事务。在SQL Server 2000,语句一旦发生异常,T-SQL将不会继续运行,上面被牺牲的连接中, print 'end tran'语句将不会被运行,所以我们很难在SQL Server 2000的T-SQL中对死锁进行进一步的处理。

现在不同了,SQL Server 2005可以在T-SQL中对异常进行捕获,这样就给我们提供了一条处理死锁的途径:

下面利用的try ... catch来解决死锁。


SET XACT_ABORT ON

declare @r int 
set @r = 1 
while @r <= 3 
begin 
    begin tran 
     
    begin try        
        insert into Orders(CustomerId) values('ALFKI') 
        waitfor delay '00:00:05' 
        select * from Orders where CustomerId = 'ALFKI' 
         
        commit 
        break 
    end try 
         
    begin catch 
        rollback 
        waitfor delay '00:00:03' 
        set @r = @r + 1 
        continue 
    end catch 
end 
解决方法当然就是重试,但捕获错误是前提。rollback后面的waitfor不可少,发生冲突后需要等待一段时间,@retry数目可以调整以应付不同的要求。

但是现在又面临一个新的问题: 错误被掩盖了,一但问题发生并且超过3次,异常却不会被抛出。SQL Server 2005 有一个RaiseError语句,可以抛出异常,但却不能直接抛出原来的异常,所以需要重新定义发生的错误,现在,解决方案变成了这样:


declare @r int 
set @r = 1 
while @r <= 3 
begin 
    begin tran 
     
    begin try        
        insert into Orders(CustomerId) values('ALFKI') 
        waitfor delay '00:00:05' 
        select * from Orders where CustomerId = 'ALFKI' 
         
        commit 
        break 
    end try 
         
    begin catch 
        rollback 
        waitfor delay '00:00:03' 
        set @r = @r + 1 
        continue 
    end catch 
end

if ERROR_NUMBER() <> 0 
begin 
    declare @ErrorMessage nvarchar(4000); 
    declare @ErrorSeverity int; 
    declare @ErrorState int;

    select  
        @ErrorMessage = ERROR_MESSAGE(), 
        @ErrorSeverity = ERROR_SEVERITY(), 
        @ErrorState = ERROR_STATE();

    raiserror (@ErrorMessage, 
               @ErrorSeverity, 
               @ErrorState 
               ); 
end 
我希望将来SQL Server 2005能够直接抛出原有异常,比如提供一个无参数的RaiseError。

因此方案有点臃肿,但将死锁问题封装到T-SQL中有助于明确职责,提高高层系统的清晰度。现在,对于DataAccess的代码,或许再也不需要考虑死锁问题了。

关键字:Server、数据库、死锁

分享到:

顶部 】 【 关闭
版权所有:佛山思海电脑网络有限公司 ©1998-2024 All Rights Reserved.
联系电话:(0757)22630313、22633833
中华人民共和国增值电信业务经营许可证: 粤B1.B2-20030321 备案号:粤B2-20030321-1
网站公安备案编号:44060602000007 交互式栏目专项备案编号:200303DD003  
察察 工商 网安 举报有奖  警警  手机打开网站