Spring事务传播机制的使用场景

Spring 的事务传播机制定义了不同的事务管理策略,决定了一个事务方法在调用另一个事务方法时如何传播事务。它允许你控制事务的行为,在不同的方法调用和不同的业务场景下,灵活地决定事务的传播方式。

Spring 提供了七种事务传播行为,分别是:

1. PROPAGATION_REQUIRED(默认行为)

  • 含义:如果当前存在事务,则加入该事务;如果没有事务,则新建一个事务。
  • 使用场景:这是最常见的事务传播方式,适用于大多数场景。比如,服务层的方法需要进行数据库操作,并且这些操作应当在同一个事务内提交。
  • 示例:如果你在一个方法中执行数据库插入操作,而这个方法调用的另一个方法也有数据库操作,那么它们会在同一个事务中运行。
@Transactional(propagation = Propagation.REQUIRED)
public void serviceMethod() {
    // 调用另一个方法,也会在同一个事务中
    anotherServiceMethod();
}

2. PROPAGATION_REQUIRES_NEW

  • 含义:无论当前是否有事务,都会创建一个新的事务。如果当前有事务,则挂起当前事务,待新事务完成后再恢复当前事务。
  • 使用场景:当你需要保证某些操作独立于外部事务时,可以使用这个传播行为。例如,某些日志操作或支付操作需要在独立的事务中执行,而不应该受到外部事务的影响。
  • 示例:在用户支付的过程中,支付操作需要有自己的事务,即使调用它的上层方法已经有事务。
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void paymentMethod() {
    // 执行支付操作,独立于外部事务
}

3. PROPAGATION_SUPPORTS

  • 含义:如果当前有事务,则加入当前事务;如果没有事务,则以非事务方式执行。
  • 使用场景:当你希望某些方法在事务环境下执行,但如果没有事务也能正常工作时,可以使用这个传播行为。比如一些查询操作,它们并不一定需要事务,但如果在事务中执行则更安全。
  • 示例:查询操作不需要事务,但是如果存在事务,查询应该在同一个事务中进行。
@Transactional(propagation = Propagation.SUPPORTS)
public void queryMethod() {
    // 执行查询操作
}

4. PROPAGATION_NOT_SUPPORTED

  • 含义:当前方法不支持事务,如果存在事务,当前事务将被挂起。
  • 使用场景:当你希望某个方法不在事务中运行,并且不允许嵌套事务时使用。例如,某些操作可能会改变系统状态,但不希望它们受到事务控制的影响,比如某些日志记录。
  • 示例:在处理文件上传或发送通知时,可以使用此传播行为。
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void logMethod() {
    // 执行日志记录,不需要事务
}

5. PROPAGATION_NEVER

  • 含义:当前方法不允许在事务中运行。如果当前有事务存在,则抛出异常。
  • 使用场景:当你不希望在事务中执行某些操作时,可以使用该传播行为。比如,某些读取配置或系统状态的操作不应该在事务上下文中执行。
  • 示例:某些操作,像配置更新或统计数据,不希望被事务包裹。
@Transactional(propagation = Propagation.NEVER)
public void systemStatusMethod() {
    // 该方法不能在事务中运行
}

6. PROPAGATION_MANDATORY

  • 含义:当前方法必须在事务中运行,如果当前没有事务,则抛出异常。
  • 使用场景:适用于一些必须在已有事务中执行的场景。如果没有外部事务,应该引发异常。可以用于要求一定要有父事务的业务场景,比如订单处理等。
  • 示例:订单处理需要确保在一个事务中完成,而不能在没有事务的情况下执行。
@Transactional(propagation = Propagation.MANDATORY)
public void orderProcessMethod() {
    // 该方法必须在已有事务中执行
}

7. PROPAGATION_ALWAYS

  • 含义:无论当前是否有事务,都会创建一个新的事务。如果当前已经存在事务,则会抛出异常。
  • 使用场景:这通常用于那些要求必须在一个新事务中执行的场景,并且不允许存在外部事务影响。比如,某些独立的业务逻辑,如全新的订单提交操作,必须是一个完全独立的事务。
  • 示例:订单提交必须是独立的操作,不能依赖外部事务。
@Transactional(propagation = Propagation.ALWAYS)
public void submitOrderMethod() {
    // 始终创建一个新的事务
}

  • PROPAGATION_REQUIRED 是最常用的事务传播方式,适用于绝大多数业务场景。
  • PROPAGATION_REQUIRES_NEW 用于需要强制新建一个独立事务的场景。
  • PROPAGATION_SUPPORTSPROPAGATION_NOT_SUPPORTED 适用于查询操作、日志记录等不需要事务的场景。
  • PROPAGATION_NEVERPROPAGATION_MANDATORY 则可以用于更严格的事务控制,确保方法的调用环境符合特定要求。

你可能感兴趣的:(spring,oracle,数据库)