在SQL Server 2005中解决死锁
数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过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的代码,或许再也不需要考虑死锁问题了。
- · 从Oracle数据库到SQL Server数据库主键的迁移
- · MS SQL 2005 安全设置
- · SQL SERVER2000备份和恢复存储过程
- · SQL Server SQL语句导入导出大全
- · 品味SQL Server 2005的几个新功能
- · 拷贝的SQL Server 7的恢复方法
- · SQL Server中各个系统表的作用
- · 掌握SQL四条最基本的数据操作语句
- · 解决SQL Server 2000之日志传送功能
- · 给SQL Server传送数组参数的变通办法
- · SQL Server数据库实用小技巧集合
- · 改善SQL Server内存管理
- · 牢记!SQL Server数据库开发的二十一条军规
- · SQL Server2000数据库系统表的应用
- · SQL Server数据库实用小技巧集合
- · SQL Server中删除重复数据的几个方法
- · SQLServer数据库安全规划全攻略
- · SQL Server 2005的30项顶尖特性
- · SqlServer下数据库链接的使用方法
- · 如何解决SQL Server 2000中的连接问题
- · SQL Server 6六种数据移动方法
- · 十大绝招保护SQL Server数据库安全
- · SQL Server连接中三个常见的错误分析
- · SQL Server 2005终于出RTM了
- · 使用SQL存储过程要特别注意的问题-注意顺序读取
- · sql*plus使用的一些技巧
- · SQL Server数据库安全规划全攻略
- · 在SQLSERVER里写了一个Split函数
- · 无法将 SQL Server 2000 MSDE Service Pack 应用到由 .NET Framework SDK 1.0 安装的 MSDE 实例
- · Sqlserver常用的时间函数---GETDATE、GETUTCDATE、DATENAME
- · Power Designer的反向工程
- · T-SQL学习笔记(1)
- · 存储过程编写经验和优化措施
- · My First PL/SQL Procedure
- · 使用正规表达式编写更好的 SQL
- · Ultraedit的SQL Server语法着色模板
- · SQL 2000中的触发器使用
- · T-SQL,动态聚合查询
- · 更改数据库对象的所有者
- · CBO与RBO下的IN/EXISTS
- · 使用SQL语句赋予SQL Server数据库登录用户权限
- · 数据库系统防黑客入侵技术综述
- · 自动安装SQL Server数据库
- · 列出SQL SERVER 所有表,字段名,主键,类型,长度,小数位数等信息
- · SRVCTL 命令详细说明文档(原译)

