SQL Server 2005中解决死锁问题

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介: SQL Server 2005中解决死锁问题  数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过SQL Server 2005, 现在似乎有了一种新的解决办法。  将下面的SQL语句放在两个不同的连接里面,并且在5秒内同时执行,将会发生死锁。

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不 

解决方法当然就是重试,但捕获错误是前提。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的代码,或许再也不需要考虑死锁问题了。
相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
8天前
|
SQL 人工智能 算法
【SQL server】玩转SQL server数据库:第二章 关系数据库
【SQL server】玩转SQL server数据库:第二章 关系数据库
51 10
|
1月前
|
SQL 数据库 数据安全/隐私保护
Sql Server数据库Sa密码如何修改
Sql Server数据库Sa密码如何修改
|
2月前
|
SQL 算法 数据库
【数据库SQL server】关系数据库标准语言SQL之数据查询
【数据库SQL server】关系数据库标准语言SQL之数据查询
95 0
|
2月前
|
SQL 算法 数据库
【数据库SQL server】关系数据库标准语言SQL之视图
【数据库SQL server】关系数据库标准语言SQL之视图
76 0
|
18天前
|
SQL
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
16 0
|
8天前
|
SQL 算法 数据库
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
68 6
|
3天前
|
SQL 安全 网络安全
IDEA DataGrip连接sqlserver 提示驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接的解决方法
IDEA DataGrip连接sqlserver 提示驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接的解决方法
8 0
|
8天前
|
SQL 存储 数据挖掘
数据库数据恢复—RAID5上层Sql Server数据库数据恢复案例
服务器数据恢复环境: 一台安装windows server操作系统的服务器。一组由8块硬盘组建的RAID5,划分LUN供这台服务器使用。 在windows服务器内装有SqlServer数据库。存储空间LUN划分了两个逻辑分区。 服务器故障&初检: 由于未知原因,Sql Server数据库文件丢失,丢失数据涉及到3个库,表的数量有3000左右。数据库文件丢失原因还没有查清楚,也不能确定数据存储位置。 数据库文件丢失后服务器仍处于开机状态,所幸没有大量数据写入。 将raid5中所有磁盘编号后取出,经过硬件工程师检测,没有发现明显的硬件故障。以只读方式将所有磁盘进行扇区级的全盘镜像,镜像完成后将所
数据库数据恢复—RAID5上层Sql Server数据库数据恢复案例
|
12天前
|
SQL 数据安全/隐私保护
SQL Server 2016安装教程
SQL Server 2016安装教程
17 1
|
12天前
|
SQL 安全 Java
SQL server 2017安装教程
SQL server 2017安装教程
14 1