Spring 事务的传播特性详解
在开发中,我们常常需要对数据进行事务管理,保证多条SQL语句的原子性,不仅加强了应用程序的稳定性,而且能够提高并发性,减少资源的消耗。Spring事务是优秀的事务管理框架之一,其中最重要的概念就是事务的传播特性。
什么是事务的传播特性
传播特性是指事务的一个属性,当一个事务方法调用另一个事务方法时,称被调用的事务方法为 被嵌套的事务方法
。在被嵌套的事务方法中,我们可以指定这个事务方法是否应该与外部事务共享,以及事务的传播行为。
Spring事务传播特性分类
Spring事务传播特性一共有7种,在不同的情况下,可以根据传播特性来决定当前的事务是否应该创建或者挂起。
(1)PROPAGATION_REQUIRED
PROPAGATION_REQUIRED是Spring默认的传播行为,表示调用此方法的事务将包含当前的事务方法中的数据操作,如果外面没有事务,就会新创建一个事务。
以下是一个示例代码:
@Transactional(propagation = Propagation.REQUIRED)
public void updateUser(User user) {
userDao.updateUser(user);
}
在这个例子中,我们使用@Transactional注解来对 updateUser
方法进行事务封装,该注解的属性 propagation 设置为 REQUIRED,表示方法必须在一个已经存在的事务中运行,如果没有,Spring 会新开一个事务并绑定到当前线程。
(2)PROPAGATION_SUPPORTS
PROPAGATION_SUPPORTS 表示当前方法必须在事务范围内执行,如果当前的方法运行在没有事务的环境下,那么就会以非事务方式运行;如果当前的方法在事务环境下运行,它会加入到当前事务中。
以下是一个示例代码:
@Transactional(propagation = Propagation.SUPPORTS)
public List<User> listUsers() {
return userDao.listUsers();
}
在这个例子中,我们使用@Transactional注解对 listUsers
方法进行了事务封装,该注解的属性 propagation 设置为 SUPPORTS,表示当前方法需要运行在一个已经存在的事务中,但如果当前环境没有事务,该方法也可以以非事务方式运行。
(3)PROPAGATION_MANDATORY
PROPAGATION_MANDATORY 表示当前方法必须运行在一个事务环境中,否则就会抛出异常。
以下是一个示例代码:
@Transactional(propagation = Propagation.MANDATORY)
public void updateUser(User user) {
userDao.updateUser(user);
}
在这个例子中,我们使用@Transactional注解对 updateUser
方法进行了事务封装,该注解的属性 propagation 设置为 MANDATORY,代表当前方法必须在一个事务中运行,否则将抛出异常。注意,只有在存在事务的情况下,该方法才能正常执行。
(4)PROPAGATION_REQUIRES_NEW
PROPAGATION_REQUIRES_NEW 表示必须开启一个新的事务,如果当前事务存在,则把当前事务挂起。
以下是一个示例代码:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateUser(User user) {
userDao.updateUser(user);
}
在这个例子中,我们使用@Transactional注解对 updateUser
方法进行了事务封装,该注解的属性 propagation 设置为 REQUIRES_NEW,代表当前方法必须开启一个新事务,且该事务与外部事务相互独立,互不干扰。该方法执行的过程中,如果外部有事务存在,外部事务会被挂起,待内部事务执行完毕后再恢复外部事务的执行。
(5)PROPAGATION_NOT_SUPPORTED
PROPAGATION_NOT_SUPPORTED 表示当前方法以非事务方式运行,如果当前存在事务,则挂起事务。
以下是一个示例代码:
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void deleteUser(User user) {
userDao.deleteUser(user);
}
在这个例子中,我们使用@Transactional注解对 deleteUser
方法进行了事务封装,该注解的属性 propagation 设置为 NOT_SUPPORTED,代表当前方法不需要在事务环境中执行,如果当前存在事务就将该事务挂起,方法执行完毕后再恢复外部事务的执行。
(6)PROPAGATION_NEVER
PROPAGATION_NEVER 表示当前方法不应该运行在事务环境中,如果当前存在事务,则抛出异常。
以下是一个示例代码:
@Transactional(propagation = Propagation.NEVER)
public void addUser(User user) {
userDao.addUser(user);
}
在这个例子中,我们使用@Transactional注解对 addUser
方法进行了事务封装,该注解的属性 propagation 设置为 NEVER,代表当前方法不应该在事务环境中执行,如果当前有事务存在,则抛出异常。
(7)PROPAGATION_NESTED
PROPAGATION_NESTED 表示当前方法必须运行在一个嵌套事务中,如果当前没有事务,则开启一个新的事务。嵌套事务是独立的事务,它能够单独提交或回滚,但是它的提交或回滚操作可能会影响父事务的状态。如果当前的事务方法抛出异常,那么只会回滚本层的事务,而不会回滚整个事务流。
以下是一个示例代码:
@Transactional(propagation = Propagation.NESTED)
public void batchUpdateUser(List<User> users) {
for (User user : users) {
userDao.updateUser(user);
}
}
在这个例子中,我们使用@Transactional注解对 batchUpdateUser
方法进行了事务封装,该注解的属性 propagation 设置为 NESTED,代表当前方法必须运行在一个嵌套事务中,如果当前不存在事务,则开启一个新的事务。在方法执行过程中,多条SQL语句组成一个完整的事务,与外部事务相互独立,但是它的提交或回滚操作可能会影响父事务的状态。
总结
Spring的事务传播特性提供了7种不同的传播行为,可以根据不同的情况来选择合适的传播特性。如果你能够正确地理解和使用事务传播特性,那么就能更好地管理和控制你的事务。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring事物的传播特性详解 - Python技术站