springboot事务

一、事务的基本概念

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

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

二、声明式事务管理

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

基本使用
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional
    public void updateUser(User user) {
        userRepository.save(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) {
    userRepository.save(user);
}
隔离级别

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

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

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

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

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

三、编程式事务管理

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

使用 TransactionTemplate
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

@Service
public class UserService {

    private final TransactionTemplate transactionTemplate;
    private final UserRepository userRepository;

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

    public void updateUser(User user) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                userRepository.save(user);
            }
        });
    }
}
使用 PlatformTransactionManager
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

@Service
public class UserService {

    private final PlatformTransactionManager transactionManager;
    private final UserRepository userRepository;

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

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

        TransactionStatus status = transactionManager.getTransaction(def);
        try {
            userRepository.save(user);
            transactionManager.commit(status);
        } catch (Exception ex) {
            transactionManager.rollback(status);
            throw ex;
        }
    }
}

四、配置事务管理器

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

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

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;

@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 注解,简单且易于使用。编程式事务管理提供了更细粒度的控制,但需要更多的代码。根据具体需求选择合适的事务管理方式,可以更好地保证应用程序的数据可靠性和性能。

  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
SpringBoot事务是通过使用@EnableTransactionManagement注解在配置类上来开启声明式事务的支持。当使用了@EnableTransactionManagement后,Spring容器会自动扫描注解@Transactional的方法和类。在需要事务的类或方法上使用@Transactional注解即可,当注解在类上时,表示该类的所有public方法都开启事务。被注解的方法成为一个事务整体,共享一个数据库连接,所有操作同时发生。如果在事务内部发生异常,则事务整体会自动回滚。 SpringBoot中的事务隔离级别可以根据具体需要进行配置。事务隔离级别包括读未提交、读已提交、可重复读和串行化。可以通过在@Transactional注解中使用isolation属性来指定事务隔离级别。例如,@Transactional(isolation = Isolation.READ_COMMITTED)表示使用读已提交的事务隔离级别。 @Transactional事务注解由SpringBoot控制,它会在执行具体逻辑时激活事务控制。事务注解的原理是AOP,通过动态代理和反射动态加上事务控制的手动代码逻辑。具体的实现是在逻辑执行前后进行反射动态增强,以实现事务控制的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [SpringBoot(八) SpringBoot中的事务](https://blog.csdn.net/qq_40772692/article/details/121476144)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [SpringBoot事务使用及回滚实现代码详解](https://download.csdn.net/download/weixin_38527978/12721854)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值