springboot事务

时间:2025-02-16 18:15:36

一、事务的基本概念

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

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

二、声明式事务管理

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

基本使用
import ;
import ;

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
         = userRepository;
    }

    @Transactional
    public void updateUser(User user) {
        (user);
    }
}

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

传播行为

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

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

示例:

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void createUser(User user) {
    (user);
}
隔离级别

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

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

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

@Transactional(timeout = 30, readOnly = true)
public User findUserById(Long id) {
    return (id).orElse(null);
}

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

三、编程式事务管理

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

使用 TransactionTemplate
import ;
import ;
import ;
import ;

@Service
public class UserService {

    private final TransactionTemplate transactionTemplate;
    private final UserRepository userRepository;

    public UserService(TransactionTemplate transactionTemplate, UserRepository userRepository) {
         = transactionTemplate;
         = userRepository;
    }

    public void updateUser(User user) {
        (new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                (user);
            }
        });
    }
}
使用 PlatformTransactionManager
import ;
import ;
import ;
import ;
import ;

@Service
public class UserService {

    private final PlatformTransactionManager transactionManager;
    private final UserRepository userRepository;

    public UserService(PlatformTransactionManager transactionManager, UserRepository userRepository) {
         = transactionManager;
         = userRepository;
    }

    public void updateUser(User user) {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        (TransactionDefinition.PROPAGATION_REQUIRED);

        TransactionStatus status = (def);
        try {
            (user);
            (status);
        } catch (Exception ex) {
            (status);
            throw ex;
        }
    }
}

四、配置事务管理器

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

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

import ;
import ;
import ;
import ;
import ;

import ;

@Configuration
@EnableTransactionManagement
public class TransactionConfig {

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
        return new TransactionTemplate(transactionManager);
    }
}

五、总结

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