@Transactional注解在Spring框架中用于声明式事务管理,确保数据的一致性和可靠性。然而,在某些情况下,@Transactional注解可能会失效。以下是一些常见的情况及原因:
通过遵循这些原则,可以最大程度地确保@Transactional注解在Spring框架中的正确性和有效性。
@Transactional
注解是 Spring 框架中用于声明式事务管理的关键注解。它通过 AOP(面向切面编程)机制在方法调用前后插入事务管理逻辑。要理解 @Transactional
的底层实现,我们需要深入到 Spring 的源代码中。
@Transactional
注解@Transactional
是一个元注解,定义在 org.springframework.transaction.annotation
包下:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
// 定义了各种属性,如传播行为、隔离级别等
Propagation propagation() default Propagation.REQUIRED;
Isolation isolation() default Isolation.DEFAULT;
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
boolean readOnly() default false;
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
}
TransactionInterceptor
类@Transactional
注解的实现依赖于 TransactionInterceptor
类,这是一个实现了 MethodInterceptor
接口的拦截器。TransactionInterceptor
负责在方法调用前开启事务,在方法调用后提交或回滚事务。
TransactionInterceptor
的关键方法invoke
方法:这是 MethodInterceptor
接口的核心方法,负责拦截方法调用并处理事务逻辑。@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
// 获取事务属性
TransactionAttributeSource tas = getTransactionAttributeSource();
TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(invocation.getMethod(), invocation.getClass()) : null);
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
// 如果没有事务属性,则直接调用目标方法
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, invocation);
Object retVal;
try {
// 执行目标方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 处理异常
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
// 提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
// 使用回调方式处理事务
else {
// It's a CallbackPreferringPlatformTransactionManager: pass a callback in order to
// avoid unnecessary intermediate transactions and allow for eager triggering of actual
// suspension at the head of the chain.
return ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus status) {
TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, invocation, status);
try {
return invocation.proceedWithInvocation();
}
catch (Throwable ex) {
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
}
});
}
}
TransactionAttributeSource
接口TransactionAttributeSource
接口用于获取方法上的事务属性。Spring 通常使用 AnnotationTransactionAttributeSource
来解析 @Transactional
注解。
PlatformTransactionManager
接口PlatformTransactionManager
是 Spring 中用于管理事务的核心接口。不同的数据访问技术有不同的实现,例如 DataSourceTransactionManager
、JpaTransactionManager
等。
创建代理对象:
拦截方法调用:
TransactionInterceptor
在方法调用前检查是否有 @Transactional
注解,并根据注解中的配置决定是否需要开启新的事务。PlatformTransactionManager
的 getTransaction
方法开始一个新的事务。处理结果和异常:
PlatformTransactionManager
的 commit
方法提交事务。PlatformTransactionManager
的 rollback
方法回滚事务。