Spring 事务的传播属性

Spring 事务的传播属性

事务的传播属性:

1.PROPAGATION_REQUIRED * :如果不存在事务则新建事务,若存在事务则加入事务,默认是这个
2.PROPAGATION_SUPPORTS:若当前没有事务,则已非事务执行
3.PROPAGATION_MANDATORY:若当前没有事务则抛出异常
4.PROPAGATION_REQUIRES_NEW:新建事务,若当前存在事务则挂起。
5.PROPAGATION_NOT_SUPPORTED:已非事务执行,若当前存在事务则挂起。
6.PROPAGATION_NEVER:已非事务执行,若当前存在事务则抛出异常
7.PROPAGATION_NESTED:若当前存在事务则在嵌套事务重执行,若不存在则新建事务

Spring事务

在Spring中,事务是通过AOP来实现的,那么一次完整的事务流程大概是这个样子:
Spring 事务的传播属性其中除业务代码的其他流程,就是事务对于业务代码的增强。

事务的先决条件

若两个DML语句想要使用同一个事务,必须保证关闭自动提交,并且使用同一个数据库连接。

事务的传播

假设有一个购物车结算服务,用户下单后需要写入订单表,清空购物车,库存-1

// 订单服务
@Transactional(propagation=Propagation.REQUIRED)
public void clearShoppingCart(...) {
	// 清空购物车
	shoppingCartMapper.clearShoppingCart(...);
	// 写入订单表
	orderService.purchase(...);
	// 减库存
	stockService.reduce(...);
}

// OrderService的写入订单
@Transactional(propagation=Propagation.REQUIRED)
public void purchase(...){...}

// stockService的减少库存
@Transactional(propagation=Propagation.REQUIRED)
public void reduce(...){...}

在上面的代码片中,clearShoppingCart事务中又调用了其他两个包含事务的方法,那么在调用时流程图可以理解成(暂不考虑异常):
Spring 事务的传播属性
在代码片中,写入订单以及减少库存的事务属性都是REQUIRED(如果不存在事务则新建事务,若存在事务则加入事务)。所以 “写入订单表开启事务”,“库存减少开启事务” 实际上都是使用的清空购物车的数据库连接。“订单事务提交” 与 “库存减少提交” 可以先理解成什么都没有做。事务的整体提交是由最后的 “清空购物车事务提交” 提交的。

其他事务传播属性

这么一看,其实其他事务属性的大概流程也能推出来,拿REQUIRED_NEW来举例,假设写入订单与减少库存的代码变成如下

// OrderService的写入订单
@Transactional(propagation=Propagation.REQUIRED_NEW)
public void purchase(...){...}

// stockService的减少库存
@Transactional(propagation=Propagation.REQUIRED)
public void reduce(...){...}

那么在 “写入订单开始事务” 时,会将清空购物车使用的连接挂起,从数据库连接池中新拿一个连接,执行DML语句后直接提交。而减少库存操作依旧会使用写入订单的数据库连接,并与写入订单操作一起提交。

上一篇:react antd form Item嵌套问题


下一篇:Cause: java.sql.SQLNonTransientConnectionException: CLIENT_PLUGIN_AUTH is required