http://www.voidcn.com/article/p-tvhtywql-tz.html
在使用注解事务的情况时,Spring会把每个方法的执行封装为AOP执行过程。每次执行被事务注解方法时,会判断是否有必要创建事务。如果创建事务成功,则继续调用业务逻辑方法。事务是在方法执行最开始阶段创建的,因此方法要越小越好。
事务的执行入口是TransactionInterceptor的invoke方法
@Override public Object invoke(final MethodInvocation invocation) throws Throwable { // Work out the target class: may be {@code null}. // The TransactionAttributeSource should be passed the target class // as well as the method, which may be from an interface. Class> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); // Adapt to TransactionAspectSupport's invokeWithinTransaction... return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() { @Override public Object proceedWithInvocation() throws Throwable { return invocation.proceed(); } }); }
而invoke是实现MethodInterceptor接口,而MethodInterceptor最后会封装成ReflectiveMethodInvocation实例执行,调用proceed方法。
public interface MethodInterceptor extends Interceptor { Object invoke(MethodInvocation invocation) throws Throwable; }
TransactionInterceptor是继承扩展了
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable { }
TransactionAspectSupport是比较关键的类,里面实现了事务很多业务逻辑。包括是否必要创建事务createTransactionIfNecessary,执行事务调用invokeWithinTransaction,选用什么事务管理器determineTransactionManager。
从invokeWithinTransaction方法名可以看出,在事务中执行调用,这个方法很关键,实现事务主要逻辑。
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean { protected Object invokeWithinTransaction(Method method, Class> targetClass, final InvocationCallback invocation) throws Throwable { // If the transaction attribute is null, the method is non-transactional. final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass); final PlatformTransactionManager tm = determineTransactionManager(txAttr); final String joinpointIdentification = methodIdentification(method, targetClass); if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) { // Standard transaction demarcation with getTransaction and commit/rollback calls. TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); Object retVal = null; try { // This is an around advice: Invoke the next interceptor in the chain. // This will normally result in a target object being invoked. retVal = invocation.proceedWithInvocation();//执行真正的业务操作,也就是DAO方法 } catch (Throwable ex) { // target invocation exception completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { cleanupTransactionInfo(txInfo); } commitTransactionAfterReturning(txInfo); return retVal; } //省略 ... }
createTransactionIfNecessary告诉我们在必要的时候才创建事务
protected TransactionInfo createTransactionIfNecessary( PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) { // If no name specified, apply method identification as transaction name. if (txAttr != null && txAttr.getName() == null) { txAttr = new DelegatingTransactionAttribute(txAttr) { @Override public String getName() { return joinpointIdentification; } }; } TransactionStatus status = null; if (txAttr != null) { if (tm != null) { status = tm.getTransaction(txAttr); } else { if (logger.isDebugEnabled()) { logger.debug("Skipping transactional joinpoint [" + joinpointIdentification + "] because no transaction manager has been configured"); } } } return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status); }
其中invocation.proceedWithInvocation()方法是一个around advice,会进行链式调用。DAO类方法就在这里执行的,执行完后,真正事务提交在commitTransactionAfterReturning中。
protected void commitTransactionAfterReturning(TransactionInfo txInfo) { if (txInfo != null && txInfo.hasTransaction()) { if (logger.isTraceEnabled()) { logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]"); } txInfo.getTransactionManager().commit(txInfo.getTransactionStatus()); } }
相关文章