spring 事务传播行为实例分析

spring 事务传播行为实例分析欢迎转载和指正 转载时请说明来源

Spring事务传播行为:

spring特有的事务传播行为,spring支持7种事务传播行为,确定客户端和被调用端的事务边界(说得通俗一点就是多个具有事务控制的service的相互调用时所形成的复杂的事务边界控制)下图所示为7钟事务传播机制

o   

传播行为

含义

PROPAGATION_REQUIREDXML文件中为REQUIRED)

表示当前方法必须在一个具有事务的上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。(如果被调用端发生异常,那么调用端和被调用端事务都将回滚

PROPAGATION_SUPPORTS(XML文件中为SUPPORTS

表示当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行

PROPAGATION_MANDATORY(XML文件中为MANDATORY

表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常

PROPAGATION_NESTED(XML文件中为NESTED)

表示如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同PROPAGATION_REQUIRED的一样

PROPAGATION_NEVERXML文件中为NEVER)

表示当方法务不应该在一个事务中运行,如果存在一个事务,则抛出异常

PROPAGATION_REQUIRES_NEW(XML文件中为REQUIRES_NEW

表示当前方法必须运行在它自己的事务中。一个新的事务将启动,而且如果有一个现有的事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行

PROPAGATION_NOT_SUPPORTEDXML文件中为NOT_SUPPORTED

表示该方法不应该在一个事务中运行。如果有一个事务正在运行,他将在运行期被挂起,直到这个事务提交或者回滚才恢复执行

 

例子讲解以上七中事务传播机制

假设有类A的方法methodB(),有类B的方法methodB().

1)     PROPAGATION_REQUIRED

如果B的方法methodB()的事务传播特性是propagation_required,那么如下图

spring 事务传播行为实例分析spring 事务传播行为实例分析

A.methodA()调用BmethodB()方法,那么如果A的方法包含事务,则B的方法则不从新开启事务,

1、  如果BmethodB()抛出异常,AmethodB()没有捕获,则AB的事务都会回滚;

2、   如果BmethodB()运行期间异常会导致BmethodB()的回滚,A如果捕获了异常,并正常提交事务,则会发生Transaction rolled back because it has been marked as rollback-only的异常。

3、  如果A的methodA()运行期间异常,则A和B的Method的事务都会被回滚

 

 

2)     PROPAGATION_SUPPORTS

如果B的方法methodB()的事务传播特性是propagation_supports,么如下图

spring 事务传播行为实例分析spring 事务传播行为实例分析

A.methodA()调用BmethodB()方法,那么如果A的方法包含事务,则B运行在此事务环境中,如果A的方法不包含事务,则B运行在非事务环境;

1、如果A没有事务,则AB的运行出现异常都不会回滚。

2、如果A有事务,Amethod方法执行抛出异常,B.methodBA.methodA都会回滚。

3、如果A有事务,B.method抛出异常,B.methodBA.methodA都会回滚,如果A捕获了B.method抛出的异常,则会出现异常Transactionrolled back because it has been marked as rollback-only

 

3)     PROPAGATION_MANDATORY

表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常,如下图调用关系:

spring 事务传播行为实例分析

spring 事务传播行为实例分析

B.methodB()事务传播特性定义为:PROPAGATION_MANDATORY

1、如果Amethoda()方法没有事务运行环境,则BmethodB()执行的时候会报如下异常:No existingtransaction found for transaction marked with propagation ‘mandatory’

2、如果AMethoda()方法有事务并且执行过程中抛出异常,则A.methoda()和B.methodb()执行的操作被回滚;

3、如果Amethoda()方法有事务,则B.methodB()抛出异常时,Amethoda()B.methodB()都会被回滚;如果A捕获了B.method抛出的异常,则会出现异常Transaction rolled back because ithas been marked as rollback-only

 

 

4)     PROPAGATION_NESTED

如有一下方法调用关系,如图:

spring 事务传播行为实例分析

BmethodB()定义的事务为PROPAGATION_NESTED

spring 事务传播行为实例分析

1、        如果AMethodA()不存在事务,则BmethodB()运行在一个新的事务中,B.method()抛出的异常,B.methodB()回滚,A.methodA()不回滚;如果A.methoda()抛出异常,则A.methodA()B.methodB()操作不回。

2、        如果AmethodA()存在事务,则Amethoda()抛出异常,则Amethoda()BMethodb()都会被回滚;

3、        如果AMethodA()存在事务,则BmethodB()抛出异常,B.methodB()回滚,如果A不捕获异常,则A.methodA()B.methodB()都会回滚,如果A捕获异常,则B.methodB()回滚,A不回滚;

5PROPAGATION_NEVER

表示事务传播特性定义为PROPAGATION_NEVER的方法不应该运行在一个事务环境中

有如下调用关系:

spring 事务传播行为实例分析spring 事务传播行为实例分析

 

如果B.methodB()的事务传播特性被定义为PROPAGATION_NEVER,则如果A.methodA()方法存在事务,则会出现异常Existingtransaction found for transaction marked with propagation ‘never’

6PROPAGATION_REQUIRES_NEW

      表示事务传播特性定义为PROPAGATION_REQUIRES_NEW的方法需要运行在一个新的事务中。

如有一下调用关系:B.methodB()事务传播特性为PROPAGATION_REQUIRES_NEW.

spring 事务传播行为实例分析

spring 事务传播行为实例分析

1、        如果A存在事务,A.methodA()抛出异常,A.methodA()的事务被回滚,但B.methodB()事务不受影响;如果B.methodB()抛出异常,A不捕获的话,A.methodA()B.methodB()的事务都会被回滚。如果A捕获的话,A.methodA()的事务不受影响但B.methodB()的事务回滚。

7) PROPAGATION_NOT_SUPPORTED

表示该方法不应该在一个事务中运行。如果有一个事务正在运行,他将在运行期被挂起,直到这个事务提交或者回滚才恢复执行。

spring 事务传播行为实例分析

spring 事务传播行为实例分析

如果B.methodB()方法传播特性被定义为:PROPAGATION_NOT_SUPPORTED

1、        如果A.methodA()存在事务,如果B.methodB()抛出异常,A.methodA()不捕获的话,A.methodA()的事务被回滚,而B.methodB()出现异常前数据库操作不受影响。如果A.methodA()捕获的话,则A.methodA()的事务不受影响,B.methodB()异常抛出前的数据操作不受影响。



 

实际场景中的七大事务传播行为的使用

1、  在一个话费充值业务处理逻辑中,有如下图所示操作:

spring 事务传播行为实例分析

spring 事务传播行为实例分析

业务需要扣款操作和创建订单操作同成功或者失败,因此,charger()order()的事务不能相互独立,需要包含在chargeHandle()的事务中;

通过以上需求,可以给charge()order()的事务传播行为定义成:PROPAGATION_MANDATORY

只要charge()或者order()抛出异常整个chargeHandle()都一起回滚,即使chargeHandle()捕获异常也没用,不允许提交事务。

2、  如果业务需求没接受到一次请求到要记录日志到数据库,如下图:

spring 事务传播行为实例分析

spring 事务传播行为实例分析

因为log()的操作不管扣款和创建订单成功与否都要生成日志,并且日志的操作成功与否不影响充值处理,所以log()方法的事务传播行为可以定义为:PROPAGATION_REQUIRES_NEW.

3、  在订单的售后处理中,更新完订单金额后,需要自动统计销售报表,如下图所示:

spring 事务传播行为实例分析

spring 事务传播行为实例分析

根据业务可知,售后是已经处理完订单的充值请求后的功能,是对订单的后续管理,统计报表report()方法耗时较长,因此,我们需要设置report()的事务传播行为为:PROPAGATION_NEVER,表示不适合在有事务的操作中调用,因为report()太耗时。

4、  在银行新增银行卡业务中,需要执行两个操作,一个是保存银行卡信息,一个是登记新创建的银行卡信息,其中登记银行卡信息成功与否不影响银行卡的创建。

spring 事务传播行为实例分析spring 事务传播行为实例分析

由以上需求,我们可知对于regster()方法的事务传播行为,可以设置为PROPAGATION_NESTEDaction()事务的回滚,regster()保存的信息就没意义,也就需要跟着回滚,而regster()的回滚不影响action()事务;insert()的事务传播行为可以设置为PROPAGATION_REQUIRED, PROPAGATION_MANDATORY,即insert()回滚事务,action()的事务必须跟着回滚。

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/214287.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午4:37
下一篇 2026年3月18日 下午4:37


相关推荐

  • Pycharm 报No module named ‘requests‘错的解决办法

    Pycharm 报No module named ‘requests‘错的解决办法1 首先检查是否安装了 requestsl 安装命令 pipinstallre 如果出现了 Requirementa 代表安装成功 l 或 piplist 显示安装 2 PyCharm 配置问题 项目的解释器配置问题 解决办法 可解决当前项目 importreques 问题 但新建一个项目可能又不行 打开

    2026年3月26日
    2
  • VS注册登录不显示界面内容「建议收藏」

    VS注册登录不显示界面内容「建议收藏」有时候在VS里登录微软账号,登录界面内容迟迟显示不出来,如下图所示.这样的问题可能是你用的公共网络,我一般是把网线拔了,用手机USB共享网络,就可以登陆了.公共网络自己的手机USB共享网络…

    2022年8月22日
    7
  • Moltbook:OpenClaw的社交网络

    Moltbook:OpenClaw的社交网络

    2026年3月13日
    2
  • Intellij IDEA创建web项目 [超详细]

    Intellij IDEA创建web项目 [超详细]接触 Java 有些年头了 相信大家已经忘记了怎么创建一个不使用构建工具和任何 JavaWeb 框架的原始 JavaWeb 项目 最近接触一个老项目 就是使用很原始的方式搭建的 虽然使用了 Spring 的技术 但是没有使用构建工具 手工管理庞大的依赖 Java 类库 而且还是 Eclipse 项目 习惯了 IDEA 不想再用回 Eclipse 而且对比把一个不使用构建工具创建的项目改成使用构建工具的项目工作量和带来的效益 决定还是先不要使用构建工具 只是改成 IDEA 项目

    2026年3月17日
    2
  • PHP和PHPINFO

    PHP和PHPINFOPHP开放源码和跨越平台,PHP可以运行在WINDOWS和多种版本的LINUX上。它不需要任何预先处理而快速反馈结果,它也不需要mod_perl的调整来使您的服务器的内存映象减小。PHP消耗的资源较少

    2022年7月4日
    26
  • Grok如何快速翻译多语言文本_Grok翻译功能使用指南

    Grok如何快速翻译多语言文本_Grok翻译功能使用指南

    2026年3月15日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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