已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
嵌套事务的回滚与提交一、嵌套事务和事务保存点的错误处理1、对于嵌套事务。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找不到对应的事务点。二、事务的嵌套 PRINT Trancount before transaction: + CAST(TRANCOUNT as char(1) BEGIN TRANPRINT After first BEGIN TRAN: + CAST(TRANCOUNT as char(1)BEGIN TRANPRINT After second BEGIN TRAN: + CAST(TRANCOUNT as char(1)COMMIT TRANPRINT After first COMMIT TRAN: + CAST(TRANCOUNT as char(1)COMMIT TRANPRINT 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 TRANPRINT After 1st BEGIN TRAN: + CAST(TRANCOUNT as char(1)BEGIN TRANPRINT After 2nd BEGIN TRAN: + CAST(TRANCOUNT as char(1)BEGIN TRANPRINT After 3rd BEGIN TRAN: + CAST(TRANCOUNT as char(1)UPDATE Data1SET value1 = 1000000WHERE Id = 1COMMIT TRANPRINT After first COMMIT TRAN: + CAST(TRANCOUNT as char(1)ROLLBACK TRANPRINT After ROLLBACK TRAN: + CAST(TRANCOUNT as char(1)SELECT * FROM Data1WHERE 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 ASSAVE TRANSACTION MyNameINSERT INTO TestAudit SELECT * FROM insertedIF (error 0)BEGIN ROLLBACK TRANSACTION MyNameEND 这也影响触发器中 BEGIN TRANSACTION 语句后面的COMMIT TRANSACTION 语句。因为 BEGIN TRANSACTION 启动一个嵌套事务,而随后的 COMMIT 语句只应用于该嵌套事务。如果在 COMMIT 之后执行 ROLLBACK TRANSACTION 语句,那么 ROLLBACK 将一直回滚到最外部的 BEGIN TRANSACTION。以下的触发器阐明了这一点:CREATE TRIGGER TestTrig ON TestTab FOR UPDATE ASBEGIN TRANSACTIONINSERT INTO TrigTarget SELECT * FROM insertedCOMMIT TRANSACTIONROLLBACK TRANSACTION 此触发器绝对不会在 TrigTarget 表中插入。BEGIN TRANSACTION 总是启动一个嵌套事务。COMMIT TRANSACTION 只提交嵌套事务,而下面的 ROLLBACK TRANSACTION 则一直回滚到最外部的 BEGIN TRANSACTION。四、嵌套事务相关SQL语句:ROLLBACK 可以回滚某个事务保存点(SAVE TRAN TranSave1), 如ROLLBACK TRAN TranSave1,但是要明白的是,回滚事务保存点并不会使事务数TranCount减少,你嵌套了几个事务,它还是有几个事务数. 特别注意,如果在父存储过程创建一个事务Tran1,然后在子存储过程执行ROLLBACK TRAN后,子存储过程会抛出异常!事务只能在同一个存储过程里面创建、回滚和提交,不允许分离在不同的存储过程里面。 基 于以上特点,我个人觉得嵌套事务的作用不大,SQL的内部处理其实最终就是处理一个最外层的事务点。SQL抛出事务相关的异常,并不是代码有何问题,而是 在提醒我们注意事务的控制。 我们只要采用TRY CATCH 方式捕获相关异常就可以,我们只要确保设计的事务点能正常回滚或提交就OK了。解决方法1: TRY CATCH 捕获相关异常解决方法2: 如果外部已经有事务了,就不再创建内部事务。我想SQL的事务异常提醒就是为了告诉你,不能随便一个地方放事务。 IF TRANCOUNT =0 BEGIN TRAN TRY CATCH 注意事项:SQL语句不加try catch,即使出现异常,后续的SQL语句也会执行。但是一旦外部加了try catch,则会捕获异常,导致后续的SQL语句没有执行。 是否SQL的异常有分致命和普遍的,在没加try catch的情况下,普通的可以继续往下走,但是致命的就不往下走了。这个和C#编程语言有重大的不同,编程语言一旦出现异常,后续代码就不再执行! 在处理嵌套事务时,要特别注意,不论如何要确保事务被完整的关闭或被回滚!回滚比较好控制。无论有多少级事务数,只要ROLLBACK 一次就可以。不过如果是ROLLBACK TRAN TRANNAME,TranName不是第一级的话,则会出现异常,等于没有执行ROLLBACK操作。 提交就要特别注意了。BEGIN TRAN 创建事务3个,则必须COMMIT TRAN 提交事务3次,才能确保事务数被完整提交。可以通过TRANCOUNT来查看当前事务数。一旦存储过程没有完整提交事务,则可能出现事务锁表的情况! 如果创建事务的进程销毁了,即使有未提交的事务,应该也销毁,算回滚了吧? BEGIN TRANSAVE TRANCOMMIT TRANROLLBACK TRAN嵌套事务示例:BEGIN TRAN Tran1BEGIN TRAN Tran2COMMIT TRAN 可以单独
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年西昌民族幼儿师范高等专科学校单招职业适应性测试模拟测试卷附答案
- 2025广东河源市龙川县粮食储备有限责任公司员工招聘5人(公共基础知识)测试题带答案解析
- 2026年铁岭师范高等专科学校单招职业适应性测试模拟测试卷附答案
- 2026年湖南汽车工程职业学院单招职业适应性考试题库及参考答案详解
- 2025秋季中国石油燃料油公司高校毕业生招聘(公共基础知识)测试题带答案解析
- 2026年重庆海联职业技术学院单招(计算机)考试备考题库及答案1套
- 2026年盘锦职业技术学院单招职业倾向性测试题库及参考答案详解1套
- 2026年毕节幼儿师范高等专科学校单招职业技能测试题库及参考答案详解1套
- 2026年甘肃有色冶金职业技术学院单招(计算机)测试模拟题库附答案
- 2026年南昌应用技术师范学院单招职业技能考试题库及完整答案详解1套
- 人教版七年级上册地理全册重要知识点每日默写小纸条(含答案)
- GB/T 6730.23-2025铁矿石钛含量的测定硫酸铁铵滴定法
- 河南2024级高中会考数学试卷
- 知名人物老舍生平介绍模板
- 学堂在线 工程伦理2.0 章节测试答案
- 2025-2030中国泥浆刀闸阀行业需求状况及应用前景预测报告
- 通信电子线路(哈尔滨工程大学)知到智慧树期末考试答案题库2025年哈尔滨工程大学
- 国企签约合作协议书
- 新生儿坏死性小肠结肠炎(NEC)诊疗指南与共识
- 电迁改监理实施细则
- 2025年山东济南历下控股集团有限公司招聘笔试参考题库含答案解析
评论
0/150
提交评论