java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot手动提交/回滚事务

SpringBoot手动提交/回滚事务实现方式

作者:一直到老到直一

在SpringBoot中,推荐使用`@Transactional`注解进行声明式事务管理,但在某些情况下,可能需要手动控制事务,可通过`TransactionTemplate`或编程式事务管理来实现,涉及获取事务管理器、开始事务、执行操作、提交或回滚事务,通常建议使用声明式事务管理,除非有特殊需求

在Spring Boot中,通常推荐使用声明式事务管理(即使用@Transactional注解)来自动处理事务的开启、提交和回滚。然而,在某些情况下,可能需要更细致地控制事务的边界,这时可能需要手动提交或回滚事务。

虽然Spring Boot本身不直接提供“手动”提交或回滚事务的API(因为Spring的PlatformTransactionManager接口被设计为抽象层,隐藏了具体事务实现的细节),但可以通过操作底层资源(如TransactionTemplateTransactionStatus)或使用编程式事务管理来间接实现这一点。

使用TransactionTemplate

TransactionTemplate提供了一种模板方法,允许在回调中执行数据库操作,并且可以配置事务的属性(如隔离级别、传播行为等)。然而,它并不直接提供“手动”提交或回滚事务的API,因为它会在回调方法执行完毕后自动提交事务(如果没有抛出异常),或者在抛出异常时自动回滚事务。

下面是一个使用 TransactionTemplate 的示例:

首先,需要在 Spring 配置中定义 TransactionTemplate bean(如果使用的是基于 Java 的配置,可以通过 @Bean 注解来定义):

@Configuration  
@EnableTransactionManagement  
public class TransactionConfig {  
  
    @Autowired  
    private PlatformTransactionManager transactionManager;  
  
    @Bean  
    public TransactionTemplate transactionTemplate() {  
        return new TransactionTemplate(transactionManager);  
    }  
}

然后,在服务类中注入 TransactionTemplate 并使用它:

@Service  
public class YourService {  
  
    @Autowired  
    private TransactionTemplate transactionTemplate;  
  
    @Autowired  
    private YourRepository yourRepository; // 假设你有一个Repository  
  
    public void performDatabaseOperations() {  
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {  
            @Override  
            protected void doInTransactionWithoutResult(TransactionStatus status) {  
                try {  
                    // 在这里执行数据库操作  
                    yourRepository.saveSomething();  
                    // 可以继续执行其他数据库操作...  
  
                    // 如果一切正常,TransactionTemplate会自动提交事务  
                    // 不需要手动调用status.commit();  
  
                } catch (RuntimeException ex) {  
                    // 如果捕获到异常,可以选择回滚事务  
                    // 注意:在TransactionCallbackWithoutResult中,通常不需要显式调用status.rollback();  
                    // 因为TransactionTemplate默认会在回调方法抛出异常时回滚事务  
                    // 但如果你想在回滚之前执行一些清理操作,可以在这里处理  
                    // 然后重新抛出异常,让TransactionTemplate知道需要回滚  
                    throw ex; // 重新抛出异常  
                }  
            }  
        });  
    }  
}

编程式事务管理

如果确实需要更细粒度的控制,可以通过PlatformTransactionManager接口来编程式地管理事务。这通常涉及以下几个步骤:

示例

以下是一个简单的示例,展示了如何在Spring Boot服务中编程式地管理事务:

@Service  
public class YourService {  
  
    @Autowired  
    private PlatformTransactionManager transactionManager;  
  
    @Autowired  
    private YourRepository yourRepository; // 假设你有一个Repository  
  
    public void yourMethod() {  
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();  
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);  
  
        TransactionStatus status = transactionManager.getTransaction(def);  
  
        try {  
            // 执行数据库操作  
            yourRepository.someDatabaseOperation();  
  
            // 提交事务  
            transactionManager.commit(status);  
        } catch (RuntimeException e) {  
            // 回滚事务  
            transactionManager.rollback(status);  
            throw e; // 可以选择重新抛出异常  
        }  
    }  
}

注意

虽然上述代码展示了如何在Spring Boot中编程式地管理事务,但在实际开发中,除非有特别的需求,否则通常建议使用声明式事务管理(即@Transactional注解),因为它更简单、更易于维护,并且与Spring的集成更加紧密。

此外,如果业务逻辑非常复杂,需要跨多个服务或方法边界控制事务,那么可能需要考虑使用分布式事务解决方案,如Spring Cloud Alibaba的Seata等。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文