Spring框架的事务管理模块,通过一系列注解提供了一种强大而灵活的方式来处理企业级Java应用程序中的事务。@Transactional
注解是这一模块的核心,它支持多种事务属性,如传播行为、隔离级别和超时设置,允许开发者以声明式的方式管理事务的边界和特性。此外,@Propagation
、@Isolation
和@EnableTransactionManagement
等注解进一步丰富了Spring的事务管理能力,使得开发者可以根据不同的业务场景定制事务策略。这些注解的使用不仅简化了事务代码的编写,还提高了应用程序的健壮性和可测试性。Spring事务管理的声明式特性,让开发者能够将业务逻辑与事务管理逻辑分离,从而创建出更加清晰、可维护的代码结构。
肖哥弹架构 跟大家“弹弹” 框架注解使用,需要代码关注
历史热点文章
- 28个验证注解,通过业务案例让你精通Java数据校验(收藏篇)
- Java 8函数式编程全攻略:43种函数式业务代码实战案例解析(收藏版)
- 69 个Spring mvc 全部注解:真实业务使用案例说明(必须收藏)
- 24 个Spring bean 全部注解:真实业务使用案例说明(必须收藏)
- MySQL索引完全手册:真实业务图文讲解17种索引运用技巧(必须收藏)
- 一个项目代码讲清楚DO/PO/BO/AO/E/DTO/DAO/ POJO/VO
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.REQUIRED
、Propagation.REQUIRES_NEW
等。
4.3 注解业务案例
java
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void someTransactionalMethod() {
// 业务逻辑
}
@Isolation
5.1 注解作用介绍 @Isolation
注解用于设置事务的隔离级别,与@Transactional
注解的isolation
属性配合使用。
5.2 注解属性介绍
-
value: 指定隔离级别,如
Isolation.READ_COMMITTED
、Isolation.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);
}
}
- 使用条件: 事务方法不应该运行在任何事务上下文中,如果存在一个活动的事务,抛出异常。
- 方法场景: 记录审计事件时,需要确保这些记录操作不会受到任何现有事务的影响,以保证审计数据的完整性。