前言

Spring是一款流行的Java开发框架,其中的事务管理功能可以简化应用程序的开发和维护。在Spring中,事务传播性定义了事务如何在多个方法之间传播。


事务传播性的概念

事务传播性定义了当在一个事务范围内执行多个事务性操作时,事务应该如何传播。

在Spring中,有7种事务传播性,分别是:

  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类似的操作。

额外补充说明下PROPAGATION_NESTED传播性,其是开启一个嵌套的事务,他是已存在事务的真正子事务。潜套事务开始执行时, 它将取得一个 savepoint。如果这个嵌套事务失败,将回滚到此 savepoint。

结合如下情况理解:
由service1#method1(@Transactional)调用 service2#method2方法(@Transactional(propagation = Propagation.NESTED)):
1、在service1#method1抛异常,service2#method2正常情况下,method1&method2一起回滚;
2、在service1#method1抛异常,service2#method2抛异常情况下,method1&method2一起回滚;
3、在service1#method1正常,service2#method2正常情况下,method1&method2一起提交;
4、在service1#method1正常,service2#method2抛异常情况下,
如果method1捕获method2异常,method2回滚,method1再提交;
如果method1未捕获method2异常,method2回滚,method1再回滚;


应用

在Spring中,可以使用@Transactional注解来指定事务的传播性,默认propagation = Propagation.REQUIRED。
例如,如果要在方法A中调用方法B,并在一个事务中处理这两个方法,可以使用以下代码:

@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
    // do something
    methodB();
    // do something
}

@Transactional(propagation = Propagation.REQUIRED)
public void methodB() {
    // do something
}

在上面的代码中,methodA和methodB都使用了PROPAGATION_REQUIRED传播性,这意味着它们将在同一个事务中执行。


如果希望在方法B中开启一个新的事务,可以使用PROPAGATION_REQUIRES_NEW传播性,如下所示:

@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
    // do something
    methodB();
    // do something
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodB() {
    // do something
}

在上面的示例中,methodA和methodB将在两个不同的事务中执行。


总结

事务传播性是Spring事务管理中一个重要的概念,可以帮助开发者在多个方法之间灵活地管理事务。通过使用@Transactional注解和合适的传播性设置,可以使应用程序具有更好的健壮性和可维护性。