在SQL Server 2005中解决死锁

2016-02-19 15:20 9 1 收藏

今天天气好晴朗处处好风光,好天气好开始,图老师又来和大家分享啦。下面给大家推荐在SQL Server 2005中解决死锁,希望大家看完后也有个好心情,快快行动吧!

【 tulaoshi.com - 编程语言 】

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

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

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

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

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的代码,或许再也不需要考虑死锁问题了。

来源:http://www.tulaoshi.com/n/20160219/1609437.html

延伸阅读
问题提出 在我的新工作中,我面临着一个问题,在product数据库中把创建的表进行归档,因为随着数据库的增长,现在需要把它们移走。同时,这些归档的表被几项工作使用,而且它还在应用程序的代码中被调用。这样移动它们就是一个非常复杂的过程。我希望能找到一种方法,尽可能减轻开发人员必须得完成的工作量,因为他们的时间非常有限...
标签: SQLServer
SQL Server数据库发生死锁时不会像ORACLE那样自动生成一个跟踪文件。有时可以在[管理]-[当前活动] 里看到阻塞信息(有时SQL Server企业管理器会因为锁太多而没有响应). 设定跟踪1204: USE MASTER DBCC TRACEON (1204,-1) 显示当前启用的所有跟踪标记的状态: DBCC TRACESTATUS(-1) 取消跟踪1204: DBCC TRACEOFF (1204,-1) ...
   现在很多网站都提供了站内的搜索功能,有的很简单在SQL语句里加一个条件如:where names like ‘%words%’就可以实现最基本的搜索了。    我们来看看功能强大一点,复杂一点的搜索是如何实现的(在SQL SERVER200/2005通过存储过程实现搜索算法)。    我们把用户的搜索可以分为以下两种: ...
最近,在项目开发过程中,碰到了数据库死锁问题,在解决问题的过程中,笔者对MySQL InnoDB引擎锁机制的理解逐步加深。 案例如下: 在使用Show innodb status检查引擎状态时,发现了死锁问题: *** (1) TRANSACTION: TRANSACTION 0 677833455, ACTIVE 0 sec, process no 11393, OS thread id 278546 starting index rea...
标签: Web开发
首先要明确一个基本原则,XML类型的数据之间以及XML类型与其它数据类型之间都是不能比较的,也就是说XML类型的数据不能出现在等号的任何一边。 大致可分为查询类,修改类和跨域查询类。 查询类包含query(),value(),exist()和nodes(). 修改类包含modify(). 跨域查询类包含sql:variable()和sql:column(). 查询类 ...

经验教程

598

收藏

42
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部