当前位置:   article > 正文

springboot事务

springboot事务

一、事务的基本概念

数据库操作中,事务(Transaction)是一个逻辑单元,由一组操作组成,这些操作要么全部成功,要么全部失败。事务具有以下四个特性,通常简称为 ACID 特性:

  1. 原子性(Atomicity): 事务中的所有操作要么全部完成,要么全部不完成,不会停留在中间状态。
  2. 一致性(Consistency): 事务执行前后,数据库的状态必须保持一致。
  3. 隔离性(Isolation): 并发事务之间互不影响,每个事务都看作数据库的唯一操作。
  4. 持久性(Durability): 一旦事务提交,其结果是永久性的,即使系统崩溃也不会丢失。

二、声明式事务管理

声明式事务管理是通过注解方式来管理事务,Spring Boot 支持使用 @Transactional 注解来声明事务。

基本使用
  1. import org.springframework.stereotype.Service;
  2. import org.springframework.transaction.annotation.Transactional;
  3. @Service
  4. public class UserService {
  5. private final UserRepository userRepository;
  6. public UserService(UserRepository userRepository) {
  7. this.userRepository = userRepository;
  8. }
  9. @Transactional
  10. public void updateUser(User user) {
  11. userRepository.save(user);
  12. }
  13. }

在上面的例子中,@Transactional 注解应用于 updateUser 方法,该方法中的所有数据库操作将作为一个事务进行。如果方法中的任何操作失败,整个事务将回滚。

传播行为

传播行为(Propagation Behavior)定义了事务的边界和行为。Spring 提供了多个传播行为选项,常见的包括:

  • REQUIRED(默认):如果当前存在事务,则加入该事务;如果没有事务,则创建一个新事务。
  • REQUIRES_NEW:总是创建一个新事务,如果当前存在事务,则将当前事务挂起。
  • SUPPORTS:如果当前存在事务,则加入该事务;如果没有事务,则以非事务方式执行。
  • NOT_SUPPORTED:总是以非事务方式执行,如果当前存在事务,则将当前事务挂起。
  • MANDATORY:如果当前存在事务,则加入该事务;如果没有事务,则抛出异常。
  • NEVER:总是以非事务方式执行,如果当前存在事务,则抛出异常。
  • NESTED:如果当前存在事务,则在当前事务中嵌套一个事务(仅支持 JDBC 事务管理器)。

示例:

  1. @Transactional(propagation = Propagation.REQUIRES_NEW)
  2. public void createUser(User user) {
  3. userRepository.save(user);
  4. }
隔离级别

隔离级别(Isolation Level)控制事务操作之间的隔离程度,防止不同事务之间的干扰。常见的隔离级别包括:

  • DEFAULT:使用数据库的默认隔离级别。
  • READ_UNCOMMITTED:允许读取未提交的数据,可能导致脏读。
  • READ_COMMITTED:只读取已提交的数据,防止脏读。
  • REPEATABLE_READ:确保在一个事务内多次读取数据时数据一致,防止不可重复读。
  • SERIALIZABLE:最高的隔离级别,完全隔离,防止脏读、不可重复读和幻读。
  1. @Transactional(isolation = Isolation.SERIALIZABLE)
  2. public void updateUser(User user) {
  3. userRepository.save(user);
  4. }
超时和只读属性

你可以为事务设置超时时间和只读属性:

  1. @Transactional(timeout = 30, readOnly = true)
  2. public User findUserById(Long id) {
  3. return userRepository.findById(id).orElse(null);
  4. }

在上面的例子中,事务将设置为只读,并且超时时间为 30 秒。

三、编程式事务管理

除了声明式事务管理,Spring 还支持编程式事务管理,通常使用 TransactionTemplatePlatformTransactionManager 进行控制。

使用 TransactionTemplate
  1. import org.springframework.stereotype.Service;
  2. import org.springframework.transaction.TransactionStatus;
  3. import org.springframework.transaction.support.TransactionCallbackWithoutResult;
  4. import org.springframework.transaction.support.TransactionTemplate;
  5. @Service
  6. public class UserService {
  7. private final TransactionTemplate transactionTemplate;
  8. private final UserRepository userRepository;
  9. public UserService(TransactionTemplate transactionTemplate, UserRepository userRepository) {
  10. this.transactionTemplate = transactionTemplate;
  11. this.userRepository = userRepository;
  12. }
  13. public void updateUser(User user) {
  14. transactionTemplate.execute(new TransactionCallbackWithoutResult() {
  15. @Override
  16. protected void doInTransactionWithoutResult(TransactionStatus status) {
  17. userRepository.save(user);
  18. }
  19. });
  20. }
  21. }
使用 PlatformTransactionManager
  1. import org.springframework.stereotype.Service;
  2. import org.springframework.transaction.PlatformTransactionManager;
  3. import org.springframework.transaction.TransactionDefinition;
  4. import org.springframework.transaction.TransactionStatus;
  5. import org.springframework.transaction.support.DefaultTransactionDefinition;
  6. @Service
  7. public class UserService {
  8. private final PlatformTransactionManager transactionManager;
  9. private final UserRepository userRepository;
  10. public UserService(PlatformTransactionManager transactionManager, UserRepository userRepository) {
  11. this.transactionManager = transactionManager;
  12. this.userRepository = userRepository;
  13. }
  14. public void updateUser(User user) {
  15. DefaultTransactionDefinition def = new DefaultTransactionDefinition();
  16. def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
  17. TransactionStatus status = transactionManager.getTransaction(def);
  18. try {
  19. userRepository.save(user);
  20. transactionManager.commit(status);
  21. } catch (Exception ex) {
  22. transactionManager.rollback(status);
  23. throw ex;
  24. }
  25. }
  26. }

四、配置事务管理器

在 Spring Boot 中,通常会自动配置 DataSourceTransactionManagerJpaTransactionManager,具体取决于你使用的数据库和持久化框架。

如果需要自定义配置,可以在配置类中定义事务管理器:

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.transaction.PlatformTransactionManager;
  4. import org.springframework.transaction.annotation.EnableTransactionManagement;
  5. import org.springframework.transaction.support.TransactionTemplate;
  6. import javax.sql.DataSource;
  7. @Configuration
  8. @EnableTransactionManagement
  9. public class TransactionConfig {
  10. @Bean
  11. public PlatformTransactionManager transactionManager(DataSource dataSource) {
  12. return new DataSourceTransactionManager(dataSource);
  13. }
  14. @Bean
  15. public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
  16. return new TransactionTemplate(transactionManager);
  17. }
  18. }

五、总结

通过 Spring Boot 的事务管理,可以有效地确保数据操作的一致性和完整性。声明式事务管理使用 @Transactional 注解,简单且易于使用。编程式事务管理提供了更细粒度的控制,但需要更多的代码。根据具体需求选择合适的事务管理方式,可以更好地保证应用程序的数据可靠性和性能。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/995270
推荐阅读
相关标签
  

闽ICP备14008679号