网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > 数据库 > SQL技巧
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
数据库:数据库教程,数据库技巧,Oracle教程,MySQL教程,Sybase教程,Access教程,DB2教程,数据库安全,数据库文摘
本月文章推荐
.SQL Server 2005性能测试实践-CP.
.Microsoft SQL Server 2005数据库.
.MS SQL Server 2005 开发之分页存.
.SQL Server COALESCE()函数的创新.
.面向对象设计过程中必须遵守的相.
.存储过程使用技巧.
.恢复误删数据(SQL Server 2000).
.在SQLSERVER2005中实现素数计算.
.SQL Server 2000的视图中必须小心.
.在SQL Server 2005中实现表的行列.
.数据库查询结果的动态排序(6).
.如何查看并导出数据表中字段的注.
.讲解设计应用程序时避免阻塞的八.
.用企业管理器连接并管理远程MS S.
.关于SQL SERVER 日志满的处理方法.
.SQL Server 存储过程嵌套示例.
.SQL Server性能的改进得益于逻辑.
.sql语句查询结果合并union all用.
.Sql server数据库备份还原另一方.
.数据库迁移的几种常用方式及优缺.

在SQL Server 2005中解决死锁

发表日期:2006-1-20


数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过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的代码,或许再也不需要考虑死锁问题了。

出处:Walkdan's blog

上一篇:SQL Server 2005 提供的分页查询支持 人气:11343
下一篇:SQL Server Express 数据库自动部署问题及解决 人气:9696
浏览全部SQL Server 2005的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐