Spring 事务传播机制

  1.REQUIRED(默认)

        描述:如果当前存在事务,则加入该事务;如果不存在,则创建一个新的事务。
        适用场景:大多数情况下使用此选项。它是最常见的传播行为,适用于大多数业务逻辑。

 示例:

@Service
public class UserService {

    @Autowired
    private OrderService orderService;

    @Transactional(propagation = Propagation.REQUIRED)
    public void createUserAndOrder() {
        // 创建用户
        createUser();
        // 创建订单
        orderService.createOrder();
    }

    private void createUser() {
        // 用户创建逻辑
        System.out.println("User created.");
    }
}

@Service
public class OrderService {

    @Transactional(propagation = Propagation.REQUIRED)
    public void createOrder() {
        // 订单创建逻辑
        System.out.println("Order created.");
    }
}

解释:
        如果 createUserAndOrder 和 createOrder 都在同一个事务中调用,它们将共享同一个事务。
        如果 createOrder 抛出异常,整个事务将回滚,包括 createUser 的操作。

2. SUPPORTS

        描述:如果当前存在事务,则加入该事务;如果不存在,则以非事务方式执行。
        适用场景:当方法不需要事务支持时使用,但可以容忍在事务中运行。例如,读取数据或生成报告。
        示例: 

@Service
public class ReportingService {

    @Transactional(propagation = Propagation.SUPPORTS)
    public void generateReport() {
        // 生成报告逻辑
        System.out.println("Report generated.");
    }
}

解释:
        如果当前有事务,generateReport 将加入该事务。
        如果没有事务,generateReport 将以非事务方式执行。 

3. MANDATORY

        描述:如果当前存在事务,则加入该事务;如果不存在,则抛出异常。
        适用场景:确保方法必须在一个已有的事务中执行。例如,某些验证逻辑必须在事务上下文中进行。
        示例:

@Service
public class ValidationService {

    @Transactional(propagation = Propagation.MANDATORY)
    public void validateData() {
        // 数据验证逻辑
        System.out.println("Data validated.");
    }
}

解释:
        如果 validateData 在没有事务的情况下被调用,会抛出 IllegalTransactionStateException 异常。
        这确保了验证逻辑始终在一个事务中执行。

4. REQUIRES_NEW

        描述:创建一个新的事务,如果当前存在事务,则将当前事务挂起。
        适用场景:需要独立于外部事务的新事务,例如日志记录或发送邮件等操作。
        示例:

@Service
public class LoggingService {

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void logActivity(String message) {
        // 日志记录逻辑
        System.out.println("Logged: " + message);
    }
}

解释:
        logActivity 总是运行在一个新的独立事务中。
        即使外部事务失败,logActivity 的事务仍然可以成功提交。

5. NOT_SUPPORTED

        描述:以非事务方式执行操作,如果当前存在事务,则暂停当前事务。
        适用场景:当方法不应该参与任何事务时使用,例如读取配置文件等操作。
        示例:

@Service
public class ConfigService {

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void readConfig() {
        // 读取配置文件逻辑
        System.out.println("Configuration read.");
    }
}

解释:
        如果当前有事务,readConfig 将暂停该事务并以非事务方式执行。
        这确保了配置读取不会受到事务的影响。

6. NEVER

        描述:以非事务方式执行,如果当前存在事务,则抛出异常。
        适用场景:确保方法永远不会在一个事务中执行。例如,健康检查或监控操作。
        示例:

@Service
public class HealthCheckService {

    @Transactional(propagation = Propagation.NEVER)
    public void checkHealth() {
        // 健康检查逻辑
        System.out.println("Health check performed.");
    }
}

解释:
        如果 checkHealth 在事务中被调用,会抛出 IllegalTransactionStateException 异常。
        确保健康检查始终以非事务方式执行。

 7. NESTED

        描述:如果当前存在事务,则在嵌套事务内执行;如果不存在,则创建一个新的事务。嵌套事务可以独立提交或回滚。
        适用场景:需要更细粒度的事务控制,例如部分操作失败不影响其他操作。
        示例:

@Service
public class TransactionalService {

    @Transactional(propagation = Propagation.REQUIRED)
    public void performOperations() {
        try {
            // 操作1
            operation1();
            // 操作2,使用嵌套事务
            operation2();
        } catch (Exception e) {
            // 操作2失败,不影响操作1
            System.out.println("Operation2 failed, but Operation1 succeeded.");
        }
    }

    @Transactional(propagation = Propagation.NESTED)
    public void operation2() {
        // 模拟一个条件导致操作2失败
        if (true) {
            throw new RuntimeException("Operation2 failed.");
        }
        System.out.println("Operation2 succeeded.");
    }

    private void operation1() {
        // 操作1逻辑
        System.out.println("Operation1 succeeded.");
    }
}

解释:
        operation2 在 performOperations 的嵌套事务中执行。
        如果 operation2 失败,只有 operation2 的事务会被回滚,而 operation1 的事务不受影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值