什么是spring中的事务传播行为?spring有哪些事务传播行为?(附简单示例)

什么是事务?

事务在计算机科学中是一个非常重要的概念,特别是在数据库管理系统(DBMS)中。事务通常是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。

具体来说,事务是一个不可分割的工作单位,由事务开始(begin transaction)事务结束(end transaction)之间执行的全体操作组成。事务中的操作要么全部执行,要么全部不执行,这称为原子性。此外,事务必须保持数据库从一个一致性状态变到另一个一致性状态,这称为一致性。

在数据库操作中,事务也用于把多个要做的操作组合成一个整体,利用事务的特性来保证操作的安全性。如果一个事务做到一半出现任何错误,就会进行回滚操作,来恢复成最初的模样。

事务的特性通常包括原子性、一致性、隔离性和持久性,这四个属性通常称为ACID特性。这些特性保证了事务在数据库系统中的正确性和可靠性。

除了在数据库管理中的应用,事务的概念也被广泛用于其他计算机科学领域,如操作系统、编程语言等。

什么是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: 如果当前存在事务,则嵌套事务作为一个子事务运行。如果没有事务,则按 PROPAGATION_REQUIRED 执行。
简单示例:

1、PROPAGATION_REQUIRED
@Transactional(propagation = Propagation.REQUIRED)  
public void method1() {  
    // 业务逻辑代码  
    method2(); // 调用另一个事务方法  
}  
  
@Transactional(propagation = Propagation.REQUIRED)  
public void method2() {  
    // 业务逻辑代码  
}

解释:如果method1()被调用时已经存在事务,则method1()加入该事务;如果method1()被调用时没有事务,则创建一个新的事务。method2()也会加入同一个事务。

2、PROPAGATION_SUPPORTS
@Transactional(propagation = Propagation.SUPPORTS)  
public void method1() {  
    // 业务逻辑代码  
    method2(); // 调用另一个事务方法  
}  
  
@Transactional(propagation = Propagation.REQUIRED)  
public void method2() {  
    // 业务逻辑代码  
}

解释:如果method1()被调用时存在事务,则method1()加入该事务;如果method1()被调用时没有事务,则以非事务的方式执行。method2()会加入同一个事务。

3、PROPAGATION_MANDATORY
@Transactional(propagation = Propagation.MANDATORY)  
public void method1() {  
    // 业务逻辑代码  
    method2(); // 调用另一个事务方法  
}  
  
@Transactional(propagation = Propagation.REQUIRED)  
public void method2() {  
    // 业务逻辑代码  
}

解释:强制要求method1()被调用时存在事务,如果当前不存在事务,则抛出异常。method2()会加入同一个事务。

4、PROPAGATION_REQUIRES_NEW
@Transactional(propagation = Propagation.REQUIRES_NEW)  
public void method1() {  
    // 业务逻辑代码  
    method2(); // 调用另一个事务方法  
}  
  
@Transactional(propagation = Propagation.REQUIRED)  
public void method2() {  
    // 业务逻辑代码  
}

解释:重新创建一个新的事务,无论method1()被调用时是否已经存在事务。method2()也会在新的事务中执行。

5、PROPAGATION_NOT_SUPPORTED
@Transactional(propagation = Propagation.NOT_SUPPORTED)  
public void method1() {  
    // 业务逻辑代码  
    method2(); // 调用另一个事务方法  
}  
  
@Transactional(propagation = Propagation.REQUIRED)  
public void method2() {  
    // 业务逻辑代码  
}

解释:以非事务方式执行method1(),如果method1()被调用时存在事务,则把当前事务挂起。method2()会加入同一个事务。

6、PROPAGATION_NEVER
@Transactional(propagation = Propagation.NEVER)  
public void method1() {  
    // 业务逻辑代码  
    method2(); // 调用另一个事务方法  
}  
  
@Transactional(propagation = Propagation.REQUIRED)  
public void method2() {  
    // 业务逻辑代码  
}

解释:以非事务方式执行method1(),如果method1()被调用时存在事务,则抛出异常。method2()无法执行,因为method1()以非事务方式执行。

7、PROPAGATION_NESTED
@Transactional(propagation = Propagation.NESTED)  
public void method1() {  
    // 业务逻辑代码  
    method2(); // 调用另一个事务方法  
}  
  
@Transactional(propagation = Propagation.REQUIRED)  
public void method2() {  
    // 业务逻辑代码  
}

解释:如果method1()被调用时存在事务,则在嵌套事务内执行。嵌套事务继承了外部事务的隔离性。如果当前不存在事务,则创建一个新的事务。method2()也会在嵌套事务中执行。

  • 44
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring事务传播行为是指在某个事务方法调用另一个事务方法时,如何处理这两个事务之间的关系,常见的传播行为有以下几种: 1. REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务,加入到这个事务。 2. SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。 3. MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常。 4. REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。 5. NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 6. NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。 7. NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则新建一个事务,并在新建的嵌套事务执行。 下面是一个使用 Spring 事务传播行为示例: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Transactional(propagation = Propagation.REQUIRED) public void updateUserName(Long userId, String userName) { User user = userDao.findUserById(userId); if (user == null) { throw new RuntimeException("User does not exist"); } user.setUserName(userName); userDao.updateUser(user); } @Transactional(propagation = Propagation.REQUIRES_NEW) public void updateUserNameWithNewTransaction(Long userId, String userName) { updateUserName(userId, userName); } @Transactional(propagation = Propagation.NESTED) public void updateUserNameWithNestedTransaction(Long userId, String userName) { updateUserName(userId, userName); } } ``` 在上面的示例,我们定义了三个方法,分别使用不同的传播行为来更新用户姓名。其,`updateUserName` 方法使用 `REQUIRED` 传播行为,如果当前不存在事务,则新建一个事务;`updateUserNameWithNewTransaction` 方法使用 `REQUIRES_NEW` 传播行为,无论当前是否存在事务,都会新建一个事务;`updateUserNameWithNestedTransaction` 方法使用 `NESTED` 传播行为,如果当前存在事务,则在嵌套事务执行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值