热门搜索:Photoshop 平面设计 Linux Vista Windows ASP.NET qq word 病毒 XP Excel 标志设计 

使用 TRY/CATCH 语句解决 SQL Server 2005 死锁

来源:未知(读取中...) 2007-5-18 【字体: 】 切换为

 

READ COMMITTED 隔离级别通过发布共享锁确保 SELECT 语句永远不读取未提交的数据。对于同一个资源,共享锁与排它锁互不兼容,请求者在发布共享锁之前必须等待排它锁释放。每个连接对于插入的数据都设置了排它锁,因此尝试读取对方插入数据的 SELECT 语句将试图解除插入数据的共享锁,但它会被阻塞。两个连接将互相阻塞,从而形成一个死锁。SQL Server 的锁定管理器检测到死锁时,将中止其中的一个批处理,回滚它的事务,释放它的阻塞锁,以便其他事务能够完成。作为死锁牺牲品的事务将回滚,其他事务则将成功完成。如何使用 TRY/CATCH 语句避免死锁

  现在,让我们来使用 TRY/CATCH 语句修改代码正文。(对于本示例,需要以 SQL Server 2005 版本运行代码。)使用 TRY/CATCH 时,操作代码和错误处理代码是分开的。您应该将执行一个操作的代码放在 TRY 语句块中,将错误处理代码放在 CATCH 语句块中。如果 TRY 语句块中的代码执行失败,代码执行将跳到 CATCH 语句块。(除了那些防碍整个批处理运行的错误(如,丢失对象),该方法几乎适用于所有的错误。)

  以下示例使用 TRY/CATCH 语句对前面使用的代码进行了改写。代码标题相同,但是代码正文不同:

BEGIN TRANSACTION
BEGIN TRY
 INSERT Authors VALUES
 (@au_id, @au_lname, '', '', '', '', '', '11111', 0)
 WAITFOR DELAY '00:00:05'
 SELECT COUNT(*) FROM Authors
 COMMIT
END TRY
BEGIN CATCH
 SELECT ERROR_NUMBER() AS ErrorNumber
 ROLLBACK
END CATCH;
SELECT @@TRANCOUNT AS '@@Trancount'

  现在,在连接到 SQL Server 2005 的并列窗口中运行这些代码,在此之前您需要确认已经删除了 authors 表格中任何可能阻止插入操作的数据;或者,您可以使用前置 DELETE 语句。

  两个窗口返回的 @@TRANCOUNT 级别都为 0,这表明仍然发生了死锁,但 TRY/CATCH 语句捕获了这次发生的死锁。死锁牺牲品的批处理没有再次中止,可在它的输出结果中看到错误:

ErrorNumber
-----------
1205
@@Trancount
-----------
0

  您应该已经发现 TRY/CATCH 语句具有的威力了。因为死锁错误能够为 CATCH 语句块所捕获,所以批处理将不再中止,T-SQL 代码也能继续执行。对于死锁牺牲品而言,死锁错误 1205 将代码放入 CATCH 语句块 — 在这里您可以使用新的错误处理函数浏览死锁错误。前置代码仅使用 ERROR_NUMBER() 函数取代 @@ERROR 变量,您也可以使用 ERROR_MESSAGE()、ERROR_PROCEDURE()、ERROR_SEVERITY() 和 ERROR_STATE()。这些函数的功能一目了然,它们提供的功能比我们以往使用的更多。

上一页  [1] [2] [3] 下一页

关注此文的读者还看过:
    用户评论
评论内容:不能超过100字,需审核,请自觉遵守互联网相关政策法规。
发表评论: 匿名发表 用户名: loading 位网友发表了评论 查看评论
(0/100)
"Mysql基础教程" 推荐文章
  • 此栏目下没有推荐文章