事务传播行为种类

Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:

1事务传播行为类型

事务传播行为类型

说明

PROPAGATION_REQUIRED

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。

PROPAGATION_SUPPORTS

支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY

使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW

新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER

以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

当使用PROPAGATION_NESTED时,底层的数据源必须基于JDBC 3.0,并且实现者需要支持保存点事务机制。

<!--Hibernate事务管理器--> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref bean="sessionFactory" /> </property> </bean> <!-- 定义事务拦截器bean--> <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <!-- 事务拦截器bean需要依赖注入一个事务管理器--> <property name="transactionManager" ref="transactionManager" /> <property name="transactionAttributes"> <!-- 下面定义事务传播属性--> <props> <prop key="save*">PROPAGATION_REQUIRED</prop> <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="delete*">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> <bean id="managerTemplate" abstract="true" lazy-init="true"> <property name="teamDao"> <ref bean="teamDao" /> </property> <property name="studentDao"> <ref bean="studentDao" /> </property> </bean> <bean id ="manager" class="com.zd.service.impl.Manager" parent="managerTemplate" /> <!-- 定义BeanNameAutoProxyCreator--> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <!-- 指定对满足哪些bean name的bean自动生成业务代理 --> <property name="beanNames"> <!-- 下面是所有需要自动创建事务代理的bean--> <list> <value>manager</value> </list> <!-- 此处可增加其他需要自动创建事务代理的bean--> </property> <!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器--> <property name="interceptorNames"> <list> <!-- 此处可增加其他新的Interceptor --> <value>transactionInterceptor</value> </list> </property> </bean> <!-- 基本数据库操作 --> <bean id="baseDao" class="com.zd.service.impl.BaseDao"> <property name="hibernateTemplate"> <ref bean="hibernateTemplate"/> </property> </bean> <!-- 班级 --> <bean id="teamDao" class="com.zd.service.impl.TeamDao"> <property name="baseDao"> <ref bean="baseDao" /> </property> </bean> <!-- 学生 --> <bean id="studentDao" class="com.zd.service.impl.StudentDao"> <property name="baseDao"> <ref bean="baseDao" /> </property> </bean> public void testSaveTeam() { Team team = new Team(); team.setTeamId(DBKeyCreator.getRandomKey(12)); team.setTeamName("Class CCC"); IManager manager = (IManager) SpringContextUtil.getContext().getBean("manager"); Student student = new Student(); student.setStudentId(DBKeyCreator.getRandomKey(13)); student.setSex(Student.SEX_FEMALE); student.setStudentName("Tom"); student.setTeamId("60FHDXDIG5JQ"); manager.saveTeamAndStu(team, student); System.out.println("Save Team and Student Success");

### Spring 中事务传播行为 (PROPAGATION) 的特点及工作原理 #### PROPAGATION_REQUIRED 当设置 `PROPAGATION_REQUIRED` 时,表示如果有现有的事务则加入该事务;如果没有现有事务,则创建一个新的事务并执行操作。这是默认的事务传播行为。 ```java @Transactional(propagation = Propagation.REQUIRED) public void methodA() { // 方法逻辑 } ``` 在这种情况下,如果另一个方法调用了此方法,并且调用者已经有一个事务上下文,则两者共享同一个事务[^1]。否则,将启动新的独立事务[^4]。 --- #### PROPAGATION_SUPPORTS 对于 `PROPAGATION_SUPPORTS` 而言,它表明当前方法可以支持事务运行环境下的执行。具体来说: - 如果已有事务存在,那么就在已有的事务范围内运作; - 若无任何活跃中的事务,则完全以非事务模式来处理业务逻辑而不抛错或中断流程。 这意味着即使没有显式的事务管理器参与其中也不会影响到程序正常运转过程[^3]。 --- #### PROPAGATION_MANDATORY 这种类型的配置强制要求目标函数必须在一个有效的事务环境中被触发。换句话说,在调用带有此类标志的方法之前应该确保外部已经有适当建立起来的一个正在进行状态下的 transaction instance 。假如违反这一前提条件——即尝试单独去激活这样一个标记为 mandatory propagation level 下的功能单元而未提供必要的 surrounding tx context ——将会引发异常情况发生。 因此,使用这种方式的前提是你非常清楚整个应用程序结构以及各个组件之间相互依赖关系如何构建而成[^2]。 --- #### PROPAGATION_REQUIRES_NEW 每当遇到指定为此种级别的请求到达服务器端口之后便会立即暂停目前可能存在的其他所有关联性的 transactions ,接着重新开启另外一条全新的 pathway 来专门服务于此次特定需求直至完成为止才返回原来的位置继续往下走原来的路线图谱之上前进下去[^5]。 以下是实现代码片段展示: ```java @Transactional(propagation = Propagation.REQUIRES_NEW) public void methodB() { // 新建事务内的逻辑 } ``` 无论外层是否有事务,都会新开一个独立的新事务来进行隔离保护。 --- #### PROPAGATION_NOT_SUPPORTED 在此设定下,实际操作会被暂时移除出原有的事务框架之外单独进行计算分析等活动直到结束再回到原先的状态之中恢复连接链路等等。 简单理解就是告诉系统:“嘿,请先放下手头上的那个复杂的账本记录任务一会儿吧,让我快速搞定下面这些简单的活儿就好啦!” 这样做有助于提高效率减少不必要的开销成本等问题出现几率哦😊! --- #### PROPAGATION_NEVER 严格禁止任何形式的存在于同一时间线里面的多个并发版本号之间的转换现象产生出来的情况发生。也就是说一旦发现还有尚未关闭完毕之前的遗留下来的旧版实例对象的话就会直接报错终止后续动作序列的发展进程咯😎! 所以当你希望绝对干净纯粹没有任何干扰因素掺杂进来的时候就可以考虑采用这样的策略方案设计思路💡! --- #### PROPAGATION_NESTED 最后介绍的就是嵌套型事务机制了。它的主要特点是允许在同一父级事务之下进一步细分层次等级从而形成更加精细可控的小范围区域单位以便更好地满足复杂场景应用场合的需求标准规范要求💪。 通过保存点(Savepoint)技术手段达成目的效果最佳表现形式如下所示👇: ```java @Transactional(propagation = Propagation.NESTED) public void nestedMethod() { // 嵌套事务的具体实现细节 } ``` 只有在支持 Savepoints 数据库管理系统上才能正常使用此项功能特性⚠️。 --- ### 总结表格对比不同种类间的差异之处 | **名称** | **描述** | |----------------------|--------------------------------------------------------------------------------------------| | REQUIRED | 存在则复用,不存在则新建 | | SUPPORTS | 支持但不强求 [^1] | | MANDATORY | 必须要有事务 | | REQUIRES_NEW | 总是新启 | | NOT_SUPPORTED | 非事务环境下运行 [^1] | | NEVER | 绝不允许事务 | | NESTED | 使用 savepoint 实现真正意义上的子事务 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值