Spring-事物传播行为

本文详细介绍了Spring框架中事务管理的七种传播属性:REQUIRED、NOT_SUPPORTED、REQUIRESNEW、MANDATORY、SUPPORTS、NEVER 和 NESTED。每种属性的作用及应用场景均进行了阐述。

 

 

spring事物的传播属性(7种)

REQUIRED(默认)
    业务方法需要在一个容器里运行。如果方法运行时,已经处在一个事务中,那么加入到这个事务,否则自己新建一个新的事务。
   存在事物,则使用当前事物;没有事物,创建新的事物 NOT_SUPPORTED 声明方法不需要事务。如果方法没有关联到一个事务,容器不会为他开启事务,如果方法在一个事务中被调用,该事务会被挂起,调用结束后,原先的事务会恢复执行。   不使用事物,如果当前存在事物,则先将事物挂起,在执行后在恢复事物 REQUIRESNEW 不管是否存在事务,该方法总汇为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务挂起,新的事务被创建。
  总是创建一个新的事物,如果存在一个事物,则将当前事物挂起,创建一个自己使用的新的事物完成后在恢复挂起的事物 MANDATORY 该方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果在没有事务的环境下被调用,容器抛出例外。 只能在事物中执行,没有事物抛出异常 SUPPORTS 该方法在某个事务范围内被调用,则方法成为该事务的一部分。如果方法在该事务范围外被调用,该方法就在没有事务的环境下执行。 有事物时使用当前事物,没有事物时则不使用事物 NEVER 该方法绝对不能在事务范围内执行。如果在就抛例外。只有该方法没有关联到任何事务,才正常执行。    不执行事物,如果当前存在事物关联,则抛出异常
NESTED 如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。
  在内部做嵌套事物

 

转载于:https://www.cnblogs.com/hwaggLee/p/4498874.html

### Spring Framework 中的事务传播行为Spring 框架中,事务传播行为决定了当前方法调用时如何处理现有事务的存在。如果存在现有事务,则按照指定的行为加入该事务;如果没有则创建新事务。具体来说: - **PROPAGATION_REQUIRED**:如果有已经存在的事务就支持这个事务,如果没有就新建一个事务[^1]。 - **PROPAGATION_SUPPORTS**:如果有已经存在的事务就支持这个事务,如果没有就不运行在一个事务里。 - **PROPAGATION_MANDATORY**:必须有一个已有的事务正在执行,否则抛出异常。 - **PROPAGATION_REQUIRES_NEW**:总是开启一个新的事务,并暂停任何现有的事务。 - **PROPAGATION_NOT_SUPPORTED**:以非事务方式执行操作,若有活动事务则挂起它。 - **PROPAGATION_NEVER**:以非事务方式执行,若当前有事务则抛出异常。 - **PROPAGATION_NESTED**:如果当前存在事务,则在嵌套事务内执行;如果不存在则创建新的事务。这依赖于底层数据库的支持,比如 MySQL 的 InnoDB 存储引擎支持保存点功能来实现真正的嵌套事务[^4]。 这些不同的传播属性可以通过 `@Transactional` 注解中的 `propagation` 属性设置,在声明式事务管理配置中非常有用。当使用编程式的事务模板 (`TransactionTemplate`) 进行耦合度较高的场景下,同样适用上述传播机制。 ```java @Transactional(propagation = Propagation.REQUIRED) public void updateOrder(Order order){ // 更新订单逻辑... } ``` #### 配置示例 为了更好地理解不同类型的传播行为,考虑下面的例子,其中展示了两个服务类之间的交互以及它们各自的事务边界是如何被定义的。 ```java @Service public class OrderService { @Autowired private ProductService productService; @Transactional(propagation = Propagation.REQUIRED) public void createOrder() { try{ // 创建订单业务逻辑... productService.updateProductStock(); } catch (Exception e) { throw new RuntimeException(e); } } } @Service public class ProductService { @Transactional(propagation = Propagation.REQUIRES_NEW) public void updateProductStock(){ // 修改库存业务逻辑... int i = 1 / 0; // 故意制造错误用于测试 // 更多更新逻辑... } } ``` 在这个例子中,`createOrder()` 方法会启动一个新的事务并尝试完成整个流程。而 `updateProductStock()` 则会在自己的独立事务上下文中执行,即使前者失败也不会影响到后者提交的结果(因为用了 `REQUIRES_NEW`),反之亦然。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值