@Transactional
注解深度解析:Spring 声明式事务的核心
@Transactional
是 Spring 框架中用于声明式事务管理的核心注解,它通过简洁的元数据配置替代了传统编程式事务的复杂模板代码。本文将从注解定义、工作原理、源码实现及最佳实践四个维度进行全面解析。
一、注解定义与核心属性
1. 注解定义
@Transactional
位于 org.springframework.transaction.annotation
包中,其完整定义如下:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
// 指定事务管理器 Bean 名称
@AliasFor("transactionManager")
String value() default "";
@AliasFor("value")
String transactionManager() default "";
// 传播行为(默认 REQUIRED)
Propagation propagation() default Propagation.REQUIRED;
// 隔离级别(默认 DEFAULT)
Isolation isolation() default Isolation.DEFAULT;
// 超时时间(秒,默认 -1)
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
// 是否只读事务(默认 false)
boolean readOnly() default false;
// 指定哪些异常触发回滚
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
// 指定哪些异常不触发回滚
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
}
2. 核心属性详解
属性 | 默认值 | 说明 |
---|---|---|
value /transactionManager | “” | 指定事务管理器 Bean 名称(多数据源场景必需) |
propagation | Propagation.REQUIRED | 事务传播行为(控制事务嵌套行为) |
isolation | Isolation.DEFAULT | 事务隔离级别(控制并发访问行为) |
timeout | -1 | 事务超时时间(秒),-1 表示使用默认值 |
readOnly | false | 是否只读事务(优化数据库性能) |
rollbackFor | {} | 指定触发回滚的异常类型(默认仅回滚 RuntimeException 和 Error ) |
noRollbackFor | {} | 指定不触发回滚的异常类型 |
二、工作原理:声明式事务的魔法
1. 核心工作流程
2. 核心组件协作
- 事务代理对象:Spring 为
@Transactional
类生成的代理(JDK 或 CGLIB) - 事务拦截器:
TransactionInterceptor
负责拦截方法调用 - 事务管理器:
PlatformTransactionManager
实现事务的开启/提交/回滚 - 事务属性源:
TransactionAttributeSource
解析@Transactional
注解
三、源码深度解析
1. 事务属性解析:AnnotationTransactionAttributeSource
public class AnnotationTransactionAttributeSource
extends AbstractTransactionAttributeSource {
// 解析方法上的 @Transactional 注解
protected TransactionAttribute findTransactionAttribute(Method method) {
return determineTransactionAttribute(method);
}
private TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
// 查找 @Transactional 注解
Transactional transactional = AnnotatedElementUtils.findMergedAnnotation(
element, Transactional.class);
if (transactional != null) {
// 将注解属性转换为 TransactionAttribute
return parseTransactionAnnotation(transactional);
}
return null;
}
protected TransactionAttribute parseTransactionAnnotation(Transactional ann) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
rbta.setPropagationBehavior(ann.propagation().value());
rbta.setIsolationLevel(ann.isolation().value());
rbta.setTimeout(ann.timeout());
rbta.setReadOnly(ann.readOnly());
rbta.setQualifier(ann.value());
// 配置回滚规则
List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
for (Class<?> rbRule : ann.rollbackFor()) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (String rbRule : ann.rollbackForClassName()) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (Class<?> rbRule : ann.noRollbackFor()) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
for (String rbRule : ann.noRollbackForClassName()) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
rbta.setRollbackRules(rollbackRules);
return rbta;
}
}
2. 事务拦截核心:TransactionInterceptor
public class TransactionInterceptor extends TransactionAspectSupport
implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null ?
AopUtils.getTargetClass(invocation.getThis()) : null);
// 在事务上下文中执行方法
return invokeWithinTransaction(
invocation.getMethod(), targetClass, new InvocationCallback() {
@Override
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();
}
});
}
}
3. 事务执行引擎:TransactionAspectSupport.invokeWithinTransaction()
public abstract class TransactionAspectSupport implements BeanFactoryAware {
protected Object invokeWithinTransaction(Method method, Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// 1. 获取事务属性
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = tas.getTransactionAttribute(method, targetClass);
// 2. 获取事务管理器
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
// 3. 创建事务
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, methodIdentification);
Object retVal;
try {
// 4. 执行业务方法
retVal = invocation.proceedWithInvocation();
} catch (Throwable ex) {
// 5. 异常处理:回滚或提交
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
} finally {
cleanupTransactionInfo(txInfo);
}
// 6. 提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
// 异常处理逻辑
protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) {
if (txInfo != null && txInfo.hasTransaction()) {
// 判断是否需要回滚
if (txInfo.transactionAttribute.rollbackOn(ex)) {
try {
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
} catch (TransactionSystemException ex2) {
// 记录回滚异常
}
} else {
try {
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
} catch (TransactionSystemException ex2) {
// 记录提交异常
}
}
}
}
}
4. 事务创建逻辑:AbstractPlatformTransactionManager
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager {
public final TransactionStatus getTransaction(TransactionDefinition definition) {
// 1. 获取当前事务(存在则根据传播行为处理)
Object transaction = doGetTransaction();
// 2. 处理传播行为
if (isExistingTransaction(transaction)) {
return handleExistingTransaction(definition, transaction);
}
// 3. 创建新事务
return startTransaction(definition, transaction);
}
private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction) {
// 设置超时时间
if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) {
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
// 设置事务超时
}
}
// 开启事务
doBegin(transaction, definition);
// 返回事务状态
return new DefaultTransactionStatus(transaction, true, false, false, false);
}
}
四、最佳实践与高级用法
1. 基础使用示例
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
// 默认事务配置
@Transactional
public Order createOrder(Order order) {
return orderRepository.save(order);
}
// 自定义事务属性
@Transactional(
propagation = Propagation.REQUIRES_NEW,
isolation = Isolation.READ_COMMITTED,
timeout = 5,
rollbackFor = PaymentException.class
)
public void processPayment(Order order) {
// 支付处理逻辑
}
}
2. 多数据源事务管理
@Configuration
public class DataSourceConfig {
@Primary
@Bean
public DataSource primaryDataSource() {
// 主数据源配置
}
@Bean
public DataSource secondaryDataSource() {
// 从数据源配置
}
@Primary
@Bean
public PlatformTransactionManager primaryTxManager(DataSource primaryDataSource) {
return new DataSourceTransactionManager(primaryDataSource);
}
@Bean
public PlatformTransactionManager secondaryTxManager(DataSource secondaryDataSource) {
return new DataSourceTransactionManager(secondaryDataSource);
}
}
// 指定事务管理器
@Service
public class ReportService {
@Transactional("secondaryTxManager")
public Report generateReport() {
// 使用从数据源
}
}
3. 嵌套事务与保存点
@Service
public class BatchProcessor {
@Transactional
public void processBatch(List<Item> items) {
for (Item item : items) {
try {
processItem(item);
} catch (Exception ex) {
// 记录错误,继续处理
}
}
}
@Transactional(propagation = Propagation.NESTED)
public void processItem(Item item) {
// 子项处理(独立保存点)
}
}
4. 事务事件监听
@Component
public class TransactionEventListener {
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handleOrderCreated(OrderCreatedEvent event) {
// 订单创建成功后发送通知
}
}
五、常见问题与解决方案
1. 事务不生效的排查
- 检查注解位置:确保
@Transactional
标注在 public 方法上 - 确认代理生效:检查 Bean 是否为代理对象(如
orderService$$EnhancerBySpringCGLIB
) - 异常类型匹配:默认只回滚
RuntimeException
和Error
// 正确配置:自定义异常触发回滚 @Transactional(rollbackFor = BusinessException.class)
- 自调用问题:同一类中方法调用不会触发代理
// 错误示例:自调用事务不生效 public void createOrder() { saveOrder(); // 不会触发事务 } @Transactional private void saveOrder() { ... }
2. 事务超时控制
@Transactional(timeout = 5) // 单位:秒
public void longRunningProcess() {
// 长时间操作
}
3. 只读事务优化
@Transactional(readOnly = true)
public List<Order> findOrdersByUser(Long userId) {
// 查询操作(数据库优化)
}
4. 分布式事务集成
结合 Atomikos 实现 JTA 分布式事务:
@Configuration
@EnableTransactionManagement
public class JtaConfig {
@Bean
public UserTransaction userTransaction() throws SystemException {
UserTransactionImp userTransaction = new UserTransactionImp();
userTransaction.setTransactionTimeout(30);
return userTransaction;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new JtaTransactionManager(userTransaction());
}
}
六、高级特性:事务同步与资源管理
1. 事务同步器(TransactionSynchronization
)
在事务生命周期中插入自定义逻辑:
public class AuditTransactionSynchronization implements TransactionSynchronization {
@Override
public void beforeCommit(boolean readOnly) {
// 提交前执行审计
}
@Override
public void afterCompletion(int status) {
// 事务完成后清理资源
}
}
// 注册同步器
TransactionSynchronizationManager.registerSynchronization(
new AuditTransactionSynchronization());
2. 资源绑定与获取
// 绑定资源到当前事务
ConnectionHolder holder = new ConnectionHolder(connection);
TransactionSynchronizationManager.bindResource(dataSource, holder);
// 从当前事务获取资源
Connection conn = DataSourceUtils.getConnection(dataSource);
七、总结
@Transactional
是 Spring 声明式事务管理的核心注解,其核心价值在于:
- 简化事务配置:通过注解替代复杂的事务模板代码
- 解耦业务逻辑:事务管理与业务代码分离
- 灵活的事务控制:支持传播行为、隔离级别等精细控制
- 统一异常处理:通过声明式方式管理事务回滚
最佳实践建议:
- 优先使用声明式事务而非编程式事务
- 显式指定
rollbackFor
确保异常处理符合预期 - 为查询方法设置
readOnly=true
优化性能 - 避免在事务方法中进行远程调用或耗时操作
- 复杂场景考虑使用
@Transactional
与编程式事务结合
理解 @Transactional
的源码实现(如 TransactionInterceptor
的工作机制),能够帮助开发者:
- 深入掌握 Spring 事务的工作原理
- 高效排查事务相关问题
- 设计更健壮的事务管理方案
- 在复杂业务场景中灵活运用事务特性