@Transactional的正确使用之事务传播行为的解疑

传送门:https://blog.youkuaiyun.com/nbl_yc/article/details/104019732 事务方法之间的调用,回滚问题

前提:事务的传播行为用在事务与事务之间,传播行为描述的是当前方法在遇到其他事务方法会怎么做

举例:

前提:abc都具有事务,ac的传播模式为默认的required

          @Transactional

         public void mainTransaction(){

                a();

                b();

                c();

        }

情况一:

          如果a,b,c的传播方式是required(自己方法的传播模式),那么abc都加入到了mainTransaction()事务中,相当于绑定状态,一个出错,全部回滚

情况二:

         如果ac的传播模式是required,b的传播模式是requiredNew,那么b异常,ab都会回滚;c要是异常,a会回滚,b因为开启了自己的事务,已经执行到数据库了,不会再回滚

总结:required是大家绑定到一块,之间互相影响。requiredNew是自己会影响到别人,但是别人出错,不会影响到自己

<think>好的,我现在需要回答用户关于@Transactional声明式事务传播行为类型的问题。首先,我得回忆一下Spring事务传播行为的相关知识。传播行为Spring事务管理中的一个重要概念,它定义了事务方法在调用其他事务方法时,事务应该如何传播。用户提到了“春秋表”,可能是笔误,应该是“传播行为类型”的列表。 根据记忆,Spring传播行为类型有七种,分别是REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED。每个类型都有不同的行为。例如,REQUIRED是默认的,如果当前没有事务,就新建一个,如果有就加入。REQUIRES_NEW则是无论当前是否存在事务,都新建一个,同时挂起当前事务。这些需要详细解释。 接下来,我需要确认这些类型是否正确,以及它们的实际应用场景。比如,MANDATORY要求必须在已有事务中运行,否则抛出异常,适用于必须要有事务支持的场景。而NOT_SUPPORTED则是在无事务状态下运行,如果当前有事务则挂起。这些区别对于正确使用事务非常重要。 然后,用户提供的引用内容中提到了Spring事务的实现原理和配置切入点表达式,这可能和传播行为的配置有关。在声明式事务中,通过@Transactional注解的属性来指定传播行为类型,比如@Transactional(propagation = Propagation.REQUIRED)。需要结合AOP的配置,如引用[2]中的切入点表达式,来定义哪些方法应用这些事务属性。 此外,要确保回答结构清晰,分点说明每种传播行为类型,并给出示例代码。同时,生成的相关问题需要覆盖用户可能感兴趣的方面,比如配置方式、嵌套事务、选择依据等。最后,引用文献需要正确对应到用户提供的引用内容,确保引用标识正确。</think>### @Transactional声明式事务传播行为类型 Spring的声明式事务通过`@Transactional`注解实现事务管理,其中`propagation`属性用于定义事务传播行为传播行为决定了事务方法在调用其他事务方法时,事务的边界如何控制。以下是7种传播行为类型及其说明: #### 1. **REQUIRED(默认)** - **行为**:如果当前存在事务,则加入该事务;否则新建一个事务。 - **应用场景**:适用于多数业务逻辑需要事务支持的场景。 - **示例**: ```java @Transactional(propagation = Propagation.REQUIRED) public void methodA() { ... } ``` #### 2. **SUPPORTS** - **行为**:如果当前存在事务,则加入;否则以非事务方式执行。 - **应用场景**:适用于查询操作,允许灵活适应调用环境。 - **示例**: ```java @Transactional(propagation = Propagation.SUPPORTS) public void queryData() { ... } ``` #### 3. **MANDATORY** - **行为**:必须在已有事务中运行,否则抛出异常。 - **应用场景**:强制要求方法必须在事务上下文中调用。 - **示例**: ```java @Transactional(propagation = Propagation.MANDATORY) public void updateData() { ... } ``` #### 4. **REQUIRES_NEW** - **行为**:无论当前是否存在事务,都新建一个事务,并挂起当前事务(如果存在)。 - **应用场景**:需要独立事务的操作(如日志记录),避免外层事务回滚影响。 - **示例**: ```java @Transactional(propagation = Propagation.REQUIRES_NEW) public void logOperation() { ... } ``` #### 5. **NOT_SUPPORTED** - **行为**:以非事务方式执行,若当前存在事务则挂起。 - **应用场景**:执行不需要事务支持的操作(如文件操作)。 - **示例**: ```java @Transactional(propagation = Propagation.NOT_SUPPORTED) public void processFile() { ... } ``` #### 6. **NEVER** - **行为**:必须在非事务环境中执行,否则抛出异常。 - **应用场景**:确保方法不会在事务中被调用。 - **示例**: ```java @Transactional(propagation = Propagation.NEVER) public void validateInput() { ... } ``` #### 7. **NESTED** - **行为**:在当前事务中创建一个嵌套事务。外层事务回滚时,嵌套事务也会回滚;但嵌套事务可独立提交或回滚。 - **支持条件**:需底层数据库支持保存点(如MySQL的InnoDB)。 - **应用场景**:复杂业务中部分操作需要独立回滚。 - **示例**: ```java @Transactional(propagation = Propagation.NESTED) public void subTask() { ... } ``` --- ### 配置传播行为的方式 在`@Transactional`注解中直接指定`propagation`属性即可: ```java @Transactional(propagation = Propagation.REQUIRED) public void transactionalMethod() { ... } ``` 通过AOP配置(如XML),可结合切入点表达式批量定义事务属性,如引用[2]中的配置: ```xml <aop:config> <aop:pointcut id="pt" expression="execution(* cn.bdqn.service.impl.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/> </aop:config> ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值