Spring事务传播行为及失效this详解

本文详细探讨了Spring事务管理中可能出现的失效情况,包括非public和static方法、this调用、异常处理等因素。同时,介绍了Spring的七大事务传播行为,如REQUIRED、SUPPORTS、REQUIRES_NEW等,并通过实例展示了它们在不同场景下的事务回滚规则。理解这些知识对于优化和调试Spring事务控制至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用this失效的场景:

  1. 无事务方法A,使用this调用开启默认事务方法B,无论在A方法中抛出异常,还是在B方法中抛出异常,方法A和方法B的操作都不会回滚。
  2. 无事务方法A,使用代理对象调用开启默认事务方法B,如果方法A抛出异常,方法A和方法B的操作都不会回滚;如果方法B抛出异常,则方法B的操作会回滚,方法A的操作不会回滚。
  3. 开启默认事务方法A,无事务方法B,方法A使用this或者代理对象调用方法B,方法A抛出异常,方法A和方法B的操作都会回滚。
  4. 开启默认事务方法A,无事务方法B,方法A使用this或者代理对象调用方法B,方法B抛出异常,方法A和方法B的操作都会回滚。
  5. 开启默认事务方法A,开启REQUIRES_NEW事务方法B,方法A使用this调用方法B,方法A抛出异常,方法A和方法B的操作都会回滚。
  6. 开启默认事务方法A,开启REQUIRES_NEW事务方法B,方法A使用this调用方法B,方法B抛出异常,方法A和方法B的操作都会回滚。
  7. 开启默认事务方法A,开启REQUIRES_NEW事务方法B,方法A使用代理对象调用方法B,方法A抛出异常,方法A的操作会回滚,方法B的操作不会回滚。
  8. 开启默认事务方法A,开启REQUIRES_NEW事务方法B,方法A使用代理对象调用方法B,方法B抛出异常,方法A和方法B的操作都会回滚。

spring七大事务传播行为:

  • PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是默认的事务传播行为。
  • PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
  • PROPAGATION_MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常。
  • PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。(一个新的事务将启动,而且如果有一个现有的事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行。)
  • PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。(外层事务抛出异常回滚,那么内层事务必须回滚,反之内层事务并不影响外层事务)

spring事务失效的原因:

  1. 非public和static方法不会被代理,所以事务也会失效
  2. 自调用this
  3. 异常抛出或者错误的异常捕获
    原因
    静态方法可以被继承,但是不能被重写,子类可以写与父类相同名称的静态方法,但是不具备动态性,子类和父类的静态方法没有继承的关系。
<think>我们正在讨论Spring事务管理相关的注解,特别是@Transactional注解。根据用户需求,需要说明@Transactional注解的用法和注意事项。同时,根据系统指令,我们需要生成相关问题,并在回答中引用时添加引用标识。注意:用户提供的引用内容是关于@Transactional注解的一些说明,我们可以参考这些内容,但需要结合我们的知识进行回答。回答结构:1.介绍@Transactional注解的作用2.详细说明@Transactional的用法(包括属性配置)3.使用注意事项(特别是代理机制导致的问题)4.提供代码示例5.生成相关问题注意:用户提供的引用[1]和引用[2]提到了一些关键点,如AOP代理、内部调用问题等,我们可以在回答中引用这些点,并自然地添加引用标识。由于用户要求使用中文,且数学公式用$...$,独立公式用$$...$$,但本问题不涉及数学公式,所以主要关注中文回答和代码格式。</think>### Spring 事务管理常用注解:@Transactional 详解 #### 一、核心注解说明 `@Transactional` 是 Spring 事务管理的核心注解,通过声明式方式管理事务边界。其原理是 Spring 通过 **AOP 代理**在方法执行前开启事务,在方法结束后根据执行结果提交或回滚事务[^1]。关键执行流程如下: ```mermaid graph LR A[调用@Transactional方法] --> B[AOP代理拦截] B --> C[PlatformTransactionManager开启事务] C --> D[执行业务逻辑] D --> E{执行成功?} E -->|是| F[提交事务] E -->|否| G[回滚事务] ``` #### 二、基础用法示例 ```java @Service public class OrderService { @Autowired private OrderRepository orderRepo; // 基本事务控制 @Transactional public void createOrder(Order order) { orderRepo.save(order); // 数据库操作 inventoryService.deductStock(); // 跨服务调用 } } ``` **关键特性**: 1. **事务传播**:通过`propagation`属性控制(默认`REQUIRED`) ```java @Transactional(propagation = Propagation.REQUIRES_NEW) ``` 2. **隔离级别**:通过`isolation`属性设置(默认`ISOLATION_DEFAULT`) ```java @Transactional(isolation = Isolation.READ_COMMITTED) ``` 3. **回滚规则**:通过`rollbackFor`/`noRollbackFor`指定异常 ```java @Transactional(rollbackFor = {SQLException.class}) ``` #### 三、使用注意事项 1. **代理机制限制** 在同一个类内部调用`@Transactional`方法时事务不生效,需通过代理对象调用[^2]: ```java // ❌ 错误:内部调用事务失效 public void process() { this.createOrder(); // 事务不生效 } // ✅ 正确:通过代理对象调用 @Autowired private OrderService selfProxy; public void process() { selfProxy.createOrder(); // 事务生效 } ``` 2. **作用域要求** 注解必须作用于`public`方法,私有方法无效。 3. **事务管理器配置** 需在配置类启用事务管理: ```java @Configuration @EnableTransactionManagement public class AppConfig { ... } ``` #### 四、高级配置属性 | 属性名 | 默认值 | 说明 | |----------------|------------------|-----------------------------| | timeout | -1 (无超时) | 事务超时时间(秒) | | readOnly | false | 是否开启只读事务(优化查询性能) | | rollbackFor | RuntimeException | 触发回滚的异常类型 | | propagation | REQUIRED | 传播行为(如REQUIRES_NEW/NESTED) | #### 五、典型应用场景 1. 银行转账操作(需保证扣款/入账原子性) 2. 订单创建(同时操作订单表/库存表) 3. 批量数据处理(失败时整体回滚) > **性能提示**:对于纯查询操作建议设置`@Transactional(readOnly=true)`,可提升数据库连接利用率[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值