嵌套事务回滚策略_内部事务回滚会导致外部事务回滚

嵌套事务回滚策略_内部事务回滚会导致外部事务回滚嵌套事务回滚策略

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

嵌套事务和事务保存点的错误处理

对于嵌套事务。

1.外部起事务,内部起事务,内外都有Try Catch
内部出错:如果内部事务出错,内部和外部事物全部回滚,外部回滚之前的操作全部不存在,但是之后的操作继续执行。
外部出错:如果外部事物出错,内部和外部事物全部回滚,外部回滚之前的操作全部不存在,但是之后的操作继续执行。
注:如果内部的事务不起事务名称,内部如果出错,将会回滚掉会话中的全部事务,而且报异常。

2.外部起事务,内部起事务,内部没有Try Catch
内部出错:如果内部事务出错,内部和外部事物全部回滚,外部回滚之前的操作全部不存在,但是之后的操作继续执行。
外部出错:如果内部事务出错,内部和外部事物全部回滚,外部回滚之前的操作全部不存在,但是之后的操作继续执行。

3.外部起事务,内部不起事务,但有Try Catch。
内部出错:外部事物正常提交,外部事物不会进入ROLLBACK,内部出错之后的记录也会正常执行。内部操作中,Try部分在错误出现之前的操作正常,Try部分在操作之后的操作不执行,然后进入Catch块中执行操作。
外部出错:内部和外部事物全部回滚,外部回滚之前的操作全部不存在,但是之后的操作继续执行。

4.外部起事务,内部不起事务,但没有Try Catch.
内部出错:如果内部事务出错,内部和外部事物全部回滚,外部回滚之前的操作全部不存在,但是之后的操作继续执行。
外部出错:如果内部事务出错,内部和外部事物全部回滚,外部回滚之前的操作全部不存在,但是之后的操作继续执行。

5.外部不起事务,内部起事务,但有Try Catch.
内部出错:外部操作被正常执行,内部ROLLBACK操作前全部回滚,之后的操作正常执行。
外部出错:出错操作之前的操作不会回滚,出错之后的操作不执行,跳入Catch块中,内部事务不会回滚。

6.外部不起事务,内部起事务,但没有Try Catch.
内部出错:外部操作被正常执行,内部ROLLBACK操作前全部回滚。由于没有catch块,所以外部操作全部执行。
外部出错:内部事务正常提交,外部只有当条记录失败,其他操作正常执行,但是有严重错误报出来。

对于事务保存点

事务保存点只有SAVE和ROLLBACK操作,当外部调用内部保存点,内部出现问题不影响外部事务,外部操作正常执行。当外部操作出现问题时,内部所有操作都回滚掉。

如:外部起事务,内部起保存点,内外都有Try Catch
内部出错:外部操作正常,不进入Catch,内部事务回滚到保存点,之后的继续执行。
外部出错:如果外部事物在保存点之前出现异常,那么外部和内部所有操作回滚。如果外部事物在保存点之前出现异常,由于保存点已经提交了事务,导致外部rollback找不到对应的事务点。

http://blog.sina.com.cn/s/blog_6003801e0100drus.html

事务的嵌套

PRINT ‘Trancount before transaction: ’ + CAST(@@TRANCOUNT as char(1))

BEGIN TRAN

PRINT ‘After first BEGIN TRAN: ’ + CAST(@@TRANCOUNT as char(1))

BEGIN TRAN

PRINT ‘After second BEGIN TRAN: ’ + CAST(@@TRANCOUNT as char(1))

COMMIT TRAN

PRINT ‘After first COMMIT TRAN: ’ + CAST(@@TRANCOUNT as char(1))

COMMIT TRAN

PRINT ‘After second COMMIT TRAN: ’ + CAST(@@TRANCOUNT as char(1))

在结果中,可以看到每一个BEGIN TRAN 语句都会使@@TRANCOUNT增加1并且每一个COMMIT TRAN语句都会使其减少1。如前所述,一个值为0的@@TRANCOUNT意味着没有打开的事务。因此,在@@TRANCOUNT值从1降到0时结束的事务发生在外层事务提交的时候。因此,每一个内部事务都需要提交。由于事务起始于第一个BEGIN TRAN并结束于最后一个COMMIT TRAN,因此最外层的事务决定了是否完全提交内部的事务。如果最外层的事务没有被提交,其中嵌套的事务也不会被提交。

键入并执行以下批来检验事务回滚时所发生的情况:

BEGIN TRAN

PRINT ‘After 1st BEGIN TRAN: ’ + CAST(@@TRANCOUNT as char(1))

BEGIN TRAN

PRINT ‘After 2nd BEGIN TRAN: ’ + CAST(@@TRANCOUNT as char(1))

BEGIN TRAN

PRINT ‘After 3rd BEGIN TRAN: ’ + CAST(@@TRANCOUNT as char(1))

UPDATE Data1

SET value1 = 1000000

WHERE Id = 1

COMMIT TRAN

PRINT ‘After first COMMIT TRAN: ’ + CAST(@@TRANCOUNT as char(1))

ROLLBACK TRAN

PRINT ‘After ROLLBACK TRAN: ’ + CAST(@@TRANCOUNT as char(1))

SELECT * FROM Data1

WHERE Id = 1;

在这个示例中,数据表Data1在一个嵌套事务中被更新,这会被立即提交。然后ROLLBACK TRAN被执行。ROLLBACK TRAN将@@TRANCOUNT减为0并回滚整个事务及其中嵌套的事务,无论它们是否已经被提交。因此,嵌套事务中所做的更新被回滚,数据没有任何改变。

始终牢记,**在嵌套的事务中,只有最外层的事务决定着是否提交内部事务。**每一个COMMIT TRAN语句总是应用于最后一个执行的BEGIN TRAN。因此,对于每一个COMMIT TRAN,必须调用一个COMMIT TRAN来提交事务。ROLLBACK TRAN语句总是属于最外层的事务,并且因此总是回滚整个事务而不论其中打开了多少嵌套事务。正因为此,管理嵌套事务很复杂。如果每一个嵌套存储过程都在自身中开始一个事务,那么嵌套事务大部分会发生在嵌套存储过程中。要避免嵌套事务,可以在过程开始处检查@@TRANCOUNT的值,以此来确定是否需要开始一个事务。如果@@TRANCOUNT大于0,因为过程已经处于一个事务中并且调用实例可以在错误发生时回滚事务。

存储过程和触发器中回滚  如果 @@TRANCOUNT 的值在存储过程完成时与过程执行时不同,则会生成一个 266 信息类错误。该错误不是由触发器中同一个条件生成的。
  
   当调用存储过程时,如果 @@TRANCOUNT 为 1 或更大,并且该过程执行 ROLLBACK TRANSACTION 或 ROLLBACK WORK 语句,则会产生 266 号错误。这是因为 ROLLBACK 回滚所有未完成的事务,并将 @@TRANCOUNT 减到 0,该值比调用过程时要小。
  
  如果在触发器中发出 ROLLBACK TRANSACTION:
  
  对当前事务中的那一点所做的所有数据修改都将回滚,包括触发器所做的修改。
  
  
  触发器继续执行 ROLLBACK 语句之后的所有其余语句。如果这些语句中的任意语句修改数据,则不回滚这些修改。执行其余的语句不会激发嵌套触发器。
  
  
  在批处理中,所有位于激发触发器的语句之后的语句都不被执行。
  
  
   触发器中的 ROLLBACK 关闭并释放所有在包含激发触发器的语句的批处理中声明和打开的游标。这其中包括了在激发触发器的批处理所调用的存储过程中声明和打开的游标。在激发触发器 的批处理之前的批处理中所声明的游标将只是关闭,但是在以下条件下,STATIC 或 INSENSITIVE 游标不关闭:
  CURSOR_CLOSE_ON_COMMIT 设置为OFF。
  
  
  静态游标要么是同步游标,要么是完全填充的异步游标。
   当执行触发器时,触发器的操作总是好像有一个未完成的事务在起作用。如果激发触发器的语句是在隐性或显式事务中,则肯定会这样。在自动提交模式下,也是 如此。当语句开始以自动提交模式执行时,如果遇到错误,则会有隐含的 BEGIN TRANSACTION 语句允许恢复该语句生成的所有修改。该隐含的事务对批处理中的其它语句没有影响,因为当语句完成时,该事务要么提交,要么回滚。但是,当调用触发器时,该 隐含的事务将仍然有效。
  
  这意味着,只要触发器中发出 BEGIN TRANSACTION 语句,则实际上就开始了一个嵌套事务。因为当回滚嵌套事务时,嵌套的 BEGIN TRANSACTION 语句将被忽略,触发器中发出的 ROLLBACK TRANSACTION 总是回滚过去该触发器本身发出的所有 BEGIN TRANSACTION 语句。ROLLBACK 回滚到最外部的 BEGIN TRANSACTION。
  
  若要在触发器中进行部分回滚,则即使总是以自动提交模式进行调用,也必须使用 SAVE TRANSACTION 语句。以下的触发器阐明了这一点:
  
  CREATE TRIGGER TestTrig ON TestTab FOR UPDATE AS
  SAVE TRANSACTION MyName
  INSERT INTO TestAudit
   SELECT * FROM inserted
  IF (@@error <> 0)
  BEGIN
   ROLLBACK TRANSACTION MyName
  END
  
   这也影响触发器中 BEGIN TRANSACTION 语句后面的COMMIT TRANSACTION 语句。因为 BEGIN TRANSACTION 启动一个嵌套事务,而随后的 COMMIT 语句只应用于该嵌套事务。如果在 COMMIT 之后执行 ROLLBACK TRANSACTION 语句,那么 ROLLBACK 将一直回滚到最外部的 BEGIN TRANSACTION。以下的触发器阐明了这一点:
  
  CREATE TRIGGER TestTrig ON TestTab FOR UPDATE AS
  BEGIN TRANSACTION
  INSERT INTO TrigTarget
   SELECT * FROM inserted
  COMMIT TRANSACTION
  ROLLBACK TRANSACTION
  
   此触发器绝对不会在 TrigTarget 表中插入。BEGIN TRANSACTION 总是启动一个嵌套事务。COMMIT TRANSACTION 只提交嵌套事务,而下面的 ROLLBACK TRANSACTION 则一直回滚到最外部的 BEGIN TRANSACTION。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/184799.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 查看Linux内核版本_ubuntu升级内核命令

    查看Linux内核版本_ubuntu升级内核命令想知道您的系统使用哪个Linux内核版本吗?以下是在Linux终端中检查内核版本的几种方法。当您需要了解系统上正在使用的确切Linux内核版本时,您可能会遇到这种情况。借助功能强大的Linux命令行,您可以轻松地找到答案。如何找到Linux内核版本在撰写本文时,我正在使用Ubuntu18.04。但是这些命令是通用的,可以在Fedora,Debian,CentOS,SUSELin…

    2022年10月13日
  • datagrip mac激活码【2021.8最新】「建议收藏」

    (datagrip mac激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容https://javaforall.cn/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~S32PGH0SQB-eyJsaWNlb…

  • 正则表达式替换自身「建议收藏」

    正则表达式替换自身「建议收藏」一、问题:将文本中所有[XXX]替换成XXX(XXX包含字母数字下划线),就是将中括号去掉了例如:[PK_Roles]   替换成:PK_Roles二、解答:正则式:\[([0-9a-zA-Z_]*)\]加圆括号表示分组并作为“反向索引”,[0-9a-zA-Z_]*表示多个数字字母下划线替换式:\1\1表示引用第1个组,\1在有些环境中是$1三、常用正则表达式空行

  • 一维条形码检测与识别原理是什么_一维条码的识别原理

    一维条形码检测与识别原理是什么_一维条码的识别原理近期在学习的内容之中的一个,整理一下,图片均为网络图片。提及的条形码主要为EAN-13码。一、概念条形码由宽度不同、反射率不同的条(黑色)和空(白色)组成。依照特定的编码规则编制,用来表达一组数字

  • 自己动手刷原生android系统

    先说几句题外话。我本人而言,用过好几种android机,有nexus系列的,也有国内厂商的产品。刷机呢,以前,1~2年之前,基本上用这大师,那助手什么的刷,一来图个方便,二来,似乎那时候从刷机软件刷进去的系统,有真正的原生android系统,或者,即使是被修改过的,绑进去的软件也还凑活,采用的欺骗手段可能也不是很多,总的说来,即使我有一点儿洁癖,也能忍。但现在情况似乎恶化了,刷机软件刷的“

  • 高精度快速阶乘算法

    高精度快速阶乘算法    我在业余时间开发了一套《超大整数完全精度快速算法库》HugeCalc,可快速计算超大整数的加、减、乘、除(商/余)、乘方、开方,也可快速计算大数的Fibonacci数列、(双)阶乘、排列、组合等,还可完成超大整数数组的最大公约数、最小公倍数等数论运算,现在,该套软件已被华军、天空、电脑之家、天天等下载站点收录。    自在网上公开以来,广受网友关注,经常有网友来联系,想交流一些算法心

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号