在ERP中,偶尔会有存储过程里面继续调用存储过程的情况

其中更有一些特殊的存储过程分别都使用了存储过程,大致可以分为下面几种情况:

1.平行事务,在多个事务中,任意一个成功则提交数据库,失败则各自ROLLBACK

  这种情况其实很简单,按顺序执行就可以了,前提是失败的存储过程不要raiserror,使用try catch捕获所有异常,通过则返回OK,失败则返回NG,即不在数据库层面抛出异常,返回一个结果集,有点类似于api调用返回结果,包含code 和 msg

2.按顺序执行,出错则回滚全部

比如我们要做一个BOM导入 ,首先需要先导入存货档案,之后再根据导入的存货档案生成BOM,如果导入存货档案的时候就失败了,那么直接回滚,同时,为保证一致性,我们在BOM导入失败时也要求回滚存货档案已经提交的信息(其实也可以先导存货档案再导BOM,但基于客户BOM和存货档案是融合在同一份EXCEL里面,所以做了一致性事务)

这个时候我们可以使用事务嵌套,下面有一个简单的示例:

CREATE TABLE #tmp1 (
  id INT,
  value NVARCHAR(10)
)
BEGIN TRY
BEGIN TRAN tr

BEGIN TRY
BEGIN TRAN tr1
SAVE TRAN point1
  INSERT INTO #tmp1(id, value)VALUES(1, N'v1')
COMMIT TRAN
END TRY
BEGIN CATCH
  ROLLBACK TRAN point1;COMMIT TRAN tr1;RAISERROR('cuowu111',16,1)
END CATCH

BEGIN TRY
BEGIN TRAN tr2
SAVE TRAN point2
  RAISERROR('error',16,1)
COMMIT TRAN
END TRY
BEGIN CATCH
  ROLLBACK TRAN point2;COMMIT TRAN tr2;RAISERROR('cuowu2222',16,1)
END CATCH

COMMIT TRAN tr
END TRY
BEGIN CATCH
ROLLBACK
END CATCH

这里使用到了SAVE TRAN point ,是因为在ROLLBACK的时候,会清空数据库中的全局变量@@trancount,而在数据库中,是以该变量判断是否存在事务的,所以当第二个commit或者rollback的时候一定会报错提交的数目不一致,报错信息:EXECUTE 后的事务计数指示 BEGIN COMMIT 语句的数目不匹配。上一计数 = 1,当前计数 = 0。

使用save tran point 保存节点,最后出错回滚再回滚到该节点,然后提交,这时相当于提交了一个空事务,效果等同于回滚了整个子事务。最后通过一个整体的父事务去包含所有子事务,我们通过读取子事务的错误信息(原则上子事务也不向外抛出异常,使用结果集记录成功或失败信息),出错则人为raiserror一个异常 ,触发父事务进行回滚。这样就可以实现多个事务的嵌套

3.那如果我们想要自定义回滚内容呢?假设一种场景,我们需要多传入一个参数来决定子存储过程是否回滚,假设我给子存储过程A传入一个值为false的参数,意思是无论A是否会出错,都不会回滚A所执行的内容。给子存储过程B传入参数true,则表示B出错一定回滚。

其实这个原理类似存储过程嵌套,不过需要我们再save point上下点功夫(因为返回的是结果集而不是raiserror,所以可以人为定义规则判断是否需要回滚)

类似的还有 B commit的时候触发 A回滚(无论A是否成功) : B先执行 ,失败后进入A,成功后则A直接 不执行

ABCDE,E出错,回滚到C:在C处定义一个point,E出错直接回滚到此处(待测试)

最后,可能有人会问那不使用嵌套事务不行吗?下一章我们讲另一个方法:内部事务与外部事务的统一

方法永远不止一个,但一定会有一个最适合的方法。

SQLServer多事务——事务嵌套的更多相关文章

  1. SQLserver锁和事务隔离级别的比较与使用(转)

    SQLserver锁和事务隔离级别的比较与使用(转) http://www.cnblogs.com/chenlulouis/archive/2010/12/06/1898014.html http:/ ...

  2. 【SqlServer】解析SqlServer中的事务

    目录结构: contents structure [+] 事务是什么 控制事务 数据并发访问产生的影响 事务的隔离级别 锁 NOLOCK.HOLDLOCK.UPDLOCK 死锁分析 在这篇Blog中, ...

  3. PLSQL_自治事务和嵌套事物的理解和用法(案例)

    2014-06-01 Created By BaoXinjian

  4. 为什么说JAVA中要慎重使用继承 C# 语言历史版本特性(C# 1.0到C# 8.0汇总) SQL Server事务 事务日志 SQL Server 锁详解 软件架构之 23种设计模式 Oracle与Sqlserver:Order by NULL值介绍 asp.net MVC漏油配置总结

    为什么说JAVA中要慎重使用继承   这篇文章的主题并非鼓励不使用继承,而是仅从使用继承带来的问题出发,讨论继承机制不太好的地方,从而在使用时慎重选择,避开可能遇到的坑. JAVA中使用到继承就会有两 ...

  5. SQLServer中的事务与锁

    事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写. 死锁:是数据库性能的 ...

  6. Spring事务传播特性的浅析——事务方法嵌套调用的迷茫

    Spring事务传播机制回顾 Spring事务一个被讹传很广说法是:一个事务方法不应该调用另一个事务方法,否则将产生两个事务.结果造成开发人员在设计事务方法时束手束脚,生怕一不小心就踩到地雷. 其实这 ...

  7. SqlServer中的事务隔离级别、锁机制

    事务 作用:用来执行一连串的动作,并且保证所有动作要么都执行.要么都不执行. 属性:原子行.一致性.隔离性.持久性 锁 作用:SqlServer使用锁来实施事务隔离属性. 阻塞 定义:如果一个事务持有 ...

  8. SQLServer存储过程中事务的使用

    create proc usp_Stock @GoodsId int, @Number int, @StockPrice money, @SupplierId int, @EmpId int, ), ...

  9. 【转】【SQLServer】SQL事务用法begin tran,commit tran和rollback tran的用法

    Sql Server 2005/2008中提供了begin tran,commit tran和rollback tran来使用事务.begin tran表示开始事务, commit tran表示提交事 ...

随机推荐

  1. asp.net core 集成 Prometheus

    asp.net core 集成 prometheus Intro Prometheus 是一个开源的现代化,云原生的系统监控框架,并且可以轻松的集成 PushGateway, AlertManager ...

  2. 【mq读书笔记】顺序消息

    注意异常情况导致整个消费无限重试 阻塞消费 mq支持局部消息顺序消费,可以确保同一个消息消费队列中的消息被顺序消费.看下针对顺序消息在整个消费过程中做的调整: 队列负载: DefaultMQPushC ...

  3. Flash----一种VirtualActor模式的分布式有状态系统原型

    首先, 这个Flash不是我们在浏览器用的Flash这种技术, 而是: 动作缓慢, 车速极快------闪电(Flash). 18年的某一个周末, 即兴用Python写了一个Virtual Actor ...

  4. 基于ARM64的Qemu/KVM学习环境搭建

    作者:pengdonglin137@163.com 在没有aarch64架构的开发板的情况下,可以使用Qemu来模拟一个支持KVM的AArch64位的host,然后再在其上运行一个开启KVM加速的Qe ...

  5. Redis/Mysql/SQLite/MongoDB 数据库对比

    一.Redis: redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(so ...

  6. this大全,还有谁??????!!!!!!!

    this在函数调用时创建,一般的对象没有this,全局window可以理解为一个函数,他有一个全局this JavaScript 语言之所以有this的设计,跟内存里面的数据结构有关系. 函数里thi ...

  7. js预解析练习

    分析下面两段代码 console.log(num)//undefined var num = 10 f()//可以执行 //f2()不可以执行 console.log(f)//function con ...

  8. 数据结构——创建链表或树节点的小trick(哑结点)

    一般创建链表时,我们可以创建一个哑结点,来保存头部  * struct ListNode {  *     int val;  *     ListNode *next;  *     ListNod ...

  9. LeetCode初级算法之数组:136 只出现一次的元素

    只出现一次的元素 题目地址:https://leetcode-cn.com/problems/single-number/ 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找 ...

  10. .Net Core ABP应用如何在阿里云Linux Docker中开启Https

    .Net Core应用开启Https本身就有很多种方式:1.代码配置2.环境变量3.反向代理 这里主要记录下阿里云的ECS,加阿里云免费的SSL证书,通过程序代码,如何进行配置. 首先从阿里云下载证书 ...