image.png Spring框架的事务管理模块,通过一系列注解提供了一种强大而灵活的方式来处理企业级Java应用程序中的事务。@Transactional注解是这一模块的核心,它支持多种事务属性,如传播行为、隔离级别和超时设置,允许开发者以声明式的方式管理事务的边界和特性。此外,@Propagation@Isolation@EnableTransactionManagement等注解进一步丰富了Spring的事务管理能力,使得开发者可以根据不同的业务场景定制事务策略。这些注解的使用不仅简化了事务代码的编写,还提高了应用程序的健壮性和可测试性。Spring事务管理的声明式特性,让开发者能够将业务逻辑与事务管理逻辑分离,从而创建出更加清晰、可维护的代码结构。

肖哥弹架构 跟大家“弹弹” 框架注解使用,需要代码关注

欢迎 点赞,关注,评论。

关注公号Solomon肖哥弹架构获取更多精彩内容

历史热点文章

6个注解说明

@Transactional

1.1 注解作用介绍

@Transactional 注解用于声明方法或类,确保它们在事务的上下文中执行。这是Spring中处理事务的最常用方式。 1.2 注解属性介绍

  • value: 指定事务管理器的名称。
  • timeout: 以秒为单位设置事务的超时时间。
  • readOnly: 指示事务是否为只读事务。
  • rollbackFor: 指定导致事务回滚的异常类数组。
  • noRollbackFor: 指定即使抛出这些异常也不触发事务回滚的类数组。
  • propagation: 指定事务的传播行为,默认为Propagation.REQUIRED
  • isolation: 指定事务的隔离级别,默认使用底层数据库的默认隔离级别。

1.3 注解业务案例

@Transactional(
    value = "customTransactionManager", 
    timeout = 5, 
    readOnly = false, 
    rollbackFor = {IllegalArgumentException.class, CustomException.class}, 
    noRollbackFor = {NoRollbackException.class}, 
    propagation = Propagation.REQUIRED,
    isolation = Isolation.READ_COMMITTED
)
public void updateUserBalance(Long userId, int amount) {
    // 业务逻辑,如更新用户余额
    accountRepository.updateBalance(userId, amount);
    if (accountRepository.getBalance(userId) < 0) {
        throw new CustomException("Insufficient funds");
    }
}

@EnableTransactionManagement

2.1 注解作用介绍

@EnableTransactionManagement 注解用于开启基于注解的事务管理,允许在Spring应用程序中使用@Transactional注解。

2.2 注解属性介绍

  • 无特定属性。

2.3 注解业务案例

@Configuration
@EnableTransactionManagement
public class TransactionManagementConfig {
    // 其他配置
}

@TransactionManagementConfigurer

3.1 注解作用介绍

@TransactionManagementConfigurer 注解用于自定义事务管理器的配置,适用于需要自定义事务管理器时。

3.2 注解属性介绍

  • 无特定属性。

3.3 注解业务案例

@Configuration
public class CustomTransactionManagementConfig implements TransactionManagementConfigurer {
    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new MyCustomTransactionManager();
    }
}

@Propagation

4.1 注解作用介绍

@Propagation 注解用于指定事务的传播行为,与@Transactional注解的propagation属性配合使用。

4.2 注解属性介绍

  • value: 指定事务的传播行为,如Propagation.REQUIREDPropagation.REQUIRES_NEW等。

4.3 注解业务案例

java
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void someTransactionalMethod() {
    // 业务逻辑
}

@Isolation

5.1 注解作用介绍 @Isolation 注解用于设置事务的隔离级别,与@Transactional注解的isolation属性配合使用。

5.2 注解属性介绍

  • value: 指定隔离级别,如Isolation.READ_COMMITTEDIsolation.REPEATABLE_READ等。

5.3 注解业务案例

java
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void someTransactionalMethod() {
    // 业务逻辑
}

@TransactionAttribute

6.1 注解作用介绍

@TransactionAttribute 注解用于指定事务的具体属性,如传播行为和隔离级别,通常与@Transactional注解配合使用。

6.2 注解属性介绍

  • value: 指定事务属性的组合。

6.3 注解业务案例

@Transactional(
    transactionAttribute = @TransactionAttribute(
        readOnly = true, 
        propagation = Propagation.SUPPORTS
    )
)
public void someTransactionalMethod() {
    // 业务逻辑
}

@Propagation@Isolation@TransactionAttribute注解通常作为@Transactional注解的参数使用,而不是单独使用。@EnableTransactionManagement@TransactionManagementConfigurer注解用于配置Spring的事务管理能力。

4种隔离策略案例说明

Isolation.DEFAULT

@Transactional(isolation = Isolation.DEFAULT)
public void processUserOrder() {
    // 业务逻辑,使用数据库默认隔离级别
}
  • 使用条件: 使用数据库默认隔离级别,适用于大多数标准业务逻辑,不特别指定隔离级别以利用数据库的默认配置,适合于那些对隔离级别没有特别要求的场景。
  • 业务案例举例: 在处理用户订单时,如果业务逻辑不涉及复杂的并发操作,使用默认隔离级别可以确保与数据库配置的一致性,同时简化事务管理。

Isolation.READ_UNCOMMITTED

@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void generateInventoryReport() {
    // 生成库存报告,允许读取未提交的数据
}
  • 使用条件: 在生成报告或统计数据时,可能不需要完全的数据一致性,此时可以牺牲一点一致性以换取更高的并发性能,适合于那些对数据实时性要求不高的报告生成场景。
  • 业务案例举例: 当生成月末库存报告时,由于报告的目的是提供概览信息,而不是用于交易处理,因此可以接受读取到未提交的事务数据。

Isolation.READ_COMMITTED

@Transactional(isolation = Isolation.READ_COMMITTED)
public void transferFunds(AccountId from, AccountId to, BigDecimal amount) {
    // 资金从一个账户转移到另一个账户
}
  • 使用条件: 保证在事务中读取的数据是其他事务已经提交的数据,适用于需要避免读取到其他未提交事务影响的数据的金融交易场景。
  • 业务案例举例: 在执行银行账户之间的资金转账时,必须确保转账操作基于已提交的账户余额,以防止出现不一致的财务记录。

Isolation.REPEATABLE_READ

@Transactional(isolation = Isolation.REPEATABLE_READ)
public void checkAndConfirmBooking(BookingId bookingId) {
    // 检查预订信息并确认预订
}
  • 使用条件: 在处理过程中需要多次读取同一数据集,保证这些数据在事务过程中的一致性,适用于库存检查和订单处理,确保库存数据不被其他事务修改。
  • 业务案例举例: 在旅游预订系统中确认客户预订时,需要多次检查房间的可用性,以确保在确认过程中房间不会被其他客户预订。

Isolation.SERIALIZABLE

@Transactional(isolation = Isolation.SERIALIZABLE)
public void updateCriticalSystemParameters() {
    // 更新关键系统参数
}
  • 使用条件: 对于更新关键配置或敏感数据,需要确保完全的隔离,避免并发访问导致的数据不一致,虽然这会牺牲一定的并发性能。
  • 业务案例举例: 当需要更新影响系统全局运行的关键参数(如交易费用率)时,使用最高隔离级别可以确保更新操作的原子性和一致性,防止配置错误。

事务7种传播机制说明

Propagation.REQUIRED

  • 案例:

    java
    public class OrderService {
        @Transactional(Propagation.REQUIRED)
        public void processOrder(Order order) {
            // 保存订单
            saveOrder(order);
            // 扣减库存
            reduceInventory(order);
        }
    }
    
  • 使用条件Propagation.REQUIRED是默认设置,适用于大多数业务逻辑,确保方法在事务上下文中执行,如果当前存在事务,则加入该事务;如果不存在,则新建一个。

  • 方法场景: 当需要执行一系列数据库操作,这些操作需要作为一个单一的原子工作单元被提交或回滚,例如处理订单时既要保存订单信息又要扣减库存。

Propagation.REQUIRES_NEW

public class UserService {
    @Transactional(Propagation.REQUIRES_NEW)
    public void deleteUser(User user) {
        // 删除用户
        userRepository.delete(user);
        // 清除用户相关数据
        clearUserData(user);
    }
}
  • 使用条件: 当需要执行一个新事务,并且这个新事务必须独立于任何现有事务时使用,即使存在一个活动的事务,REQUIRES_NEW也会创建一个新的事务。
  • 方法场景: 在删除用户时,可能需要确保删除操作在一个新的事务中执行,以避免由于现有事务的回滚而影响到删除操作。

Propagation.SUPPORTS

public class ProductService {
    @Transactional(Propagation.SUPPORTS)
    public List<Product> listProducts() {
        // 返回产品列表
        return productService.findAll();
    }
}
  • 使用条件: 当事务方法被调用时,如果已经存在一个事务,它应该在该事务的上下文中执行;如果没有事务存在,它应该非事务性地执行。
  • 方法场景: 查询操作,如列出所有产品的列表,如果存在事务,则在事务中执行查询,否则进行普通的查询。

Propagation.MANDATORY

public class AccountService {
    @Transactional(Propagation.MANDATORY)
    public void transferFunds(Account from, Account to, BigDecimal amount) {
        // 从from账户扣款
        from.debit(amount);
        // 给to账户加款
        to.credit(amount);
    }
}
  • 使用条件: 事务方法是在一个必须存在事务的上下文中被调用,如果不存在事务,抛出异常。
  • 方法场景: 执行资金转账时,必须确保在事务的上下文中执行,以保证资金的准确性和一致性。

Propagation.NESTED

public class TransactionService {
    @Transactional
    public void executeTransactions() {
        // 开启一个事务
        performTransaction();
        // 嵌套事务,进行更细粒度的操作
        @Transactional(Propagation.NESTED)
        performNestedTransaction();
    }
}
  • 使用条件: 需要在现有的事务中执行一个或多个操作,这些操作需要自己的事务上下文,例如,保存点或额外的隔离级别。
  • 方法场景: 在执行一系列需要额外事务控制的事务时,如在主事务中执行额外的事务以处理更细粒度的业务逻辑。

Propagation.NOT_SUPPORTED

public class CacheService {
    @Transactional(Propagation.NOT_SUPPORTED)
    public void refreshCache() {
        // 刷新缓存,不需要事务
        cacheManager.clearCache();
    }
}
  • 使用条件: 事务方法不应该运行在任何事务上下文中,如果存在一个活动的事务,它应该被挂起。
  • 方法场景: 执行不需要事务的操作,如刷新缓存,以避免与可能存在的事务冲突。

Propagation.NEVER

public class AuditService {
    @Transactional(Propagation.NEVER)
    public void logAuditEvent(AuditEvent event) {
        // 记录审计事件,不允许在事务上下文中执行
        auditRepository.save(event);
    }
}
  • 使用条件: 事务方法不应该运行在任何事务上下文中,如果存在一个活动的事务,抛出异常。
  • 方法场景: 记录审计事件时,需要确保这些记录操作不会受到任何现有事务的影响,以保证审计数据的完整性。