在springboot中如何使用事务

事务简介

事务(Transaction)是基于关系型数据库(RDBMS)的企业级应用的重要组成部分。在软件开发领域,事务扮演者十分重要的角色,用来确保应用程序数据的完整性和一致性。
事务具有 4 个特性:原子性、一致性、隔离性和持久性,简称为 ACID 特性。
原子性(Atomicity):一个事务是一个不可分割的工作单位,事务中包括的动作要么都做要么都
不做。
一致性(Consistency):事务必须保证数据库从一个一致性状态变到另一个一致性状态,一致性
和原子性是密切相关的。
隔离性(Isolation):一个事务的执行不能被其它事务干扰,即一个事务内部的操作及使用的数据
对并发的其它事务是隔离的,并发执行的各个事务之间不能互相打扰。
持久性(Durability):持久性也称为永久性,指一个事务一旦提交,它对数据库中数据的改变就
是永久性的,后面的其它操作和故障都不应该对其有任何影响

在 Spring Boot 中使用事务管理非常方便,Spring 提供了声明式编程式两种事务管理方式,推荐使用声明式事务(基于注解)。以下是详细的使用方法:

1. 启用事务管理

在 Spring Boot 主类上添加@EnableTransactionManagement注解(实际上 Spring Boot 默认已启用,此步骤通常可省略):

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication
@EnableTransactionManagement // 启用事务管理(可选,Spring Boot默认已启用)
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

2. 声明式事务(推荐)

在 Service 层的方法上添加@Transactional注解:

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    // 整个方法在一个事务中执行
    @Transactional
    public void transferMoney(Long fromUserId, Long toUserId, double amount) {
        // 查询账户
        User fromUser = userRepository.findById(fromUserId).orElseThrow();
        User toUser = userRepository.findById(toUserId).orElseThrow();

        // 转账操作
        fromUser.setBalance(fromUser.getBalance() - amount);
        toUser.setBalance(toUser.getBalance() + amount);

        // 保存修改
        userRepository.save(fromUser);
        userRepository.save(toUser);

        // 如果中间发生异常,所有操作都会回滚
        if (amount > 1000) {
            throw new RuntimeException("金额过大,模拟异常");
        }
    }
}

3. 事务属性配置

@Transactional注解支持多种属性配置:

@Transactional(
    propagation = Propagation.REQUIRED, // 传播行为
    isolation = Isolation.READ_COMMITTED, // 隔离级别
    timeout = 30, // 超时时间(秒)
    readOnly = false, // 是否只读
    rollbackFor = {Exception.class} // 指定需要回滚的异常类型
)
public void complexOperation() {
    // ...
}

4. 事务传播行为

控制事务如何与现有事务交互,常见的传播行为:

REQUIRED(默认):如果存在事务则加入,否则创建新事务。

REQUIRES_NEW:总是创建新事务,挂起当前事务。

SUPPORTS:支持当前事务,若无则以非事务方式执行。

NOT_SUPPORTED:以非事务方式执行,挂起当前事务。

MANDATORY:必须在现有事务中执行,否则抛出异常。

5. 异常处理与回滚

默认情况下,Spring 事务只对RuntimeException及其子类触发回滚。

可通过rollbackFor属性指定需要回滚的异常类型:

@Transactional(rollbackFor = {Exception.class}) // 所有异常都回滚

6. 编程式事务(较少使用)

通过TransactionTemplatePlatformTransactionManager手动管理事务:

@Autowired
private TransactionTemplate transactionTemplate;

public void manualTransaction() {
    transactionTemplate.execute(status -> {
        try {
            // 业务逻辑
            return true;
        } catch (Exception e) {
            status.setRollbackOnly(); // 手动回滚
            return false;
        }
    });
}

7. 多数据源事务管理

如果使用多个数据源,需要配置JtaTransactionManager(JTA 分布式事务)或使用@Transactionalvalue属性指定事务管理器:

@Transactional("secondTransactionManager")
public void secondDbOperation() {
    // ...
}

注意:

  1. 事务边界@Transactional注解的方法必须是 public,且只能被外部调用触发。
  2. 异常捕获:若在事务方法内部捕获异常而不抛出,可能导致事务不回滚。
  3. 嵌套事务:慎用嵌套事务,避免REQUIRES_NEW导致性能问题。
  4. 只读事务:对只读操作设置readOnly = true提升性能。

 示例:多操作原子性保证

@Service
public class OrderService {

    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private InventoryRepository inventoryRepository;

    @Transactional
    public void createOrder(Order order) {
        // 扣减库存
        inventoryRepository.decreaseStock(order.getProductId(), order.getQuantity());
        
        // 创建订单
        orderRepository.save(order);
        
        // 如果后续操作失败,库存扣减和订单创建都会回滚
        if (order.getAmount() > 10000) {
            throw new BusinessException("订单金额过大");
        }
    }
}

### SpringBoot 中实现事务管理的方法与配置 SpringBoot 提供了多种方式来实现事务管理,主要包括基于注解的事务控制、全局事务配置以及通过配置类统一管理事务。以下是详细说明: #### 1. 基于注解的事务管理 在 SpringBoot 中,事务管理器已经在启动时通过 `TransactionAutoConfiguration` 自动加载[^1]。因此,只需要在需要添加事务支持的方法或类上使用 `@Transactional` 注解即可实现事务功能。 - **方法级别**:将 `@Transactional` 添加到具体的方法上。 - **类级别**:将 `@Transactional` 添加到整个类上,这样该类中的所有方法都会默认启用事务。 ```java import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class UserService { @Transactional public void addUser() { // 业务逻辑 } } ``` #### 2. 全局事务配置 对于大型项目,如果每个方法都需要添加 `@Transactional` 注解,会导致代码重复和维护困难。此时可以通过 AOP 实现全局事务管理[^2]。 - **AOP 配置**:定义一个切面类,通过切入点匹配指定的方法前缀(如 `add`, `update`, `delete`),并对这些方法统一进行事务控制。 ```java import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @Aspect @Component public class TransactionAspect { @Pointcut("execution(* com.example.service.*.*(..))") public void serviceMethod() {} @Transactional public void transactionalServiceMethod() { serviceMethod(); } } ``` #### 3. 使用配置类统一管理事务 为了进一步简化事务管理,可以通过定义一个事务配置类来集中管理事务规则[^3]。这种方式可以避免在每个业务类中重复添加 `@Transactional` 注解。 - **定义事务配置类**:创建一个配置类,并通过 `@EnableTransactionManagement` 和 `@Bean` 定义事务管理器。 ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; @Configuration public class TransactionConfig { @Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } } ``` #### 注意事项 - 确保数据库连接池已正确配置,例如通过 `application.properties` 或 `application.yml` 文件设置数据源信息。 - 如果事务未生效,请检查是否满足以下条件: - 方法必须是公共的 (`public`)。 - 事务方法不能被同一类中的其他方法调用(即自我调用问题)。 - 数据源和事务管理器已正确加载。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值