@Override@Nullablepublic 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...//调用父类TransactionAspectSupport的模板方法//执行目标方法invocation.proceedreturninvokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);}
@Nullableprotected Object invokeWithinTransaction(Method method,@Nullable Class<?> targetClass,final InvocationCallback invocation)throws Throwable {// If the transaction attribute is null, the method is non-transactional.//1.获取事物属性源,(如果为空则表示不存在事物)
TransactionAttributeSource tas =getTransactionAttributeSource();//2.属性源得到目标类和方法有关的属性final TransactionAttribute txAttr =(tas != null ? tas.getTransactionAttribute(method, targetClass): null);//3.根据事物属性获取对应的事物管理器,一般是DataSourceTransactionManagerfinal PlatformTransactionManager tm =determineTransactionManager(txAttr);//4.获取目标方法唯一标识(类.方法,如com.xx.XxImpl.f1方法)final String joinpointIdentification =methodIdentification(method, targetClass, txAttr);//5.根据条件执行目标增强if(txAttr == null ||!(tm instanceofCallbackPreferringPlatformTransactionManager)){// Standard transaction demarcation with getTransaction and commit/rollback calls.//6.判断是否有必要创建一个事物,根据事物传播行为决定,参考3.1 createTransactionIfNecessary方法分析
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.//7.回调目标方法,内部执行拦截链调用,并返回结果
retVal = invocation.proceedWithInvocation();}catch(Throwable ex){//8.异常回滚 target invocation exceptioncompleteTransactionAfterThrowing(txInfo, ex);throw ex;}finally{//9.清理工作cleanupTransactionInfo(txInfo);}//10.没有异常,内部提交事物commitTransactionAfterReturning(txInfo);return retVal;}//11.else逻辑是编程式事物,不做重点关注else{//代码省略,节约篇幅...}}
publicfinal TransactionStatus getTransaction(@Nullable TransactionDefinition definition)throws TransactionException {//1.调用子类实现来获取一个事物
Object transaction =doGetTransaction();//2.没有事物定义信息就new一个if(definition == null){// Use defaults if no transaction definition given.
definition =newDefaultTransactionDefinition();}//3.判断是否已存在事物,根据传播属性处理并返回,处理除PROPAGATION_MANDATORY之外的全部可能情况if(isExistingTransaction(transaction))// Existing transaction found -> check propagation behavior to find out how to behave.returnhandleExistingTransaction(definition, transaction, debugEnabled);}//4.检查事物超时检查if(definition.getTimeout()< TransactionDefinition.TIMEOUT_DEFAULT){thrownewInvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());}//5.走到这里说明当前没有事物,PROPAGATION_MANDATORY模式下当前没有事物需要抛出异常// No existing transaction found -> check propagation behavior to find out how to proceed.if(definition.getPropagationBehavior()== TransactionDefinition.PROPAGATION_MANDATORY){thrownewIllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'");}//6.若是PROPAGATION_REQUIRED/PROPAGATION_REQUIRES_NEW/PROPAGATION_NESTED类型之一则开启一个新事务elseif(definition.getPropagationBehavior()== TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior()== TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior()== TransactionDefinition.PROPAGATION_NESTED){
SuspendedResourcesHolder suspendedResources =suspend(null);if(debugEnabled){
logger.debug("Creating new transaction with name ["+ definition.getName()+"]: "+ definition);}try{boolean newSynchronization =(getTransactionSynchronization()!= SYNCHRONIZATION_NEVER);//7.如果需要开启事物,先创建一个DefaultTransactionStatus, //后面的回滚、提交等操作是根据这个属性来判断是否在这个TransactionStatus上来进行。
DefaultTransactionStatus status =newTransactionStatus(
definition, transaction,true, newSynchronization, debugEnabled, suspendedResources);//8.开启事物doBegin(transaction, definition);//9.事物管理器相关设置prepareSynchronization(status, definition);return status;}catch(RuntimeException| Error ex){resume(null, suspendedResources);throw ex;}}else{// Create "empty" transaction: no actual transaction, but potentially synchronization.if(definition.getIsolationLevel()!= TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()){
logger.warn("Custom isolation level specified but no actual transaction initiated; "+"isolation level will effectively be ignored: "+ definition);}boolean newSynchronization =(getTransactionSynchronization()== SYNCHRONIZATION_ALWAYS);returnprepareTransactionStatus(definition, null,true, newSynchronization, debugEnabled, null);}}
protectedvoiddoBegin(Object transaction, TransactionDefinition definition){
DataSourceTransactionObject txObject =(DataSourceTransactionObject) transaction;
Connection con = null;try{if(!txObject.hasConnectionHolder()||
txObject.getConnectionHolder().isSynchronizedWithTransaction()){//1.从数据源获取连接
Connection newCon =obtainDataSource().getConnection();//2.为当前Transaction设置ConnectionHolder,并且设置newConnectionHolder为true
txObject.setConnectionHolder(newConnectionHolder(newCon),true);}
txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
con = txObject.getConnectionHolder().getConnection();//3.根据definition对connection进行一些设置,比如隔离级别
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,// so we don't want to do it unnecessarily (for example if we've explicitly// configured the connection pool to set it already).if(con.getAutoCommit()){
txObject.setMustRestoreAutoCommit(true);//4.开启事务,设置autoCommit为false
con.setAutoCommit(false);}prepareTransactionalConnection(con, definition);
txObject.getConnectionHolder().setTransactionActive(true);int timeout =determineTimeout(definition);if(timeout != TransactionDefinition.TIMEOUT_DEFAULT){
txObject.getConnectionHolder().setTimeoutInSeconds(timeout);}// Bind the connection holder to the thread.if(txObject.isNewConnectionHolder()){//将当前connection放入TransactionSynchronizationManager中持有,如果下次调用可以判断为已有的事务
TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());}}catch(Throwable ex){if(txObject.isNewConnectionHolder()){
DataSourceUtils.releaseConnection(con,obtainDataSource());
txObject.setConnectionHolder(null,false);}thrownewCannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);}}
protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,@Nullable TransactionAttribute txAttr, String joinpointIdentification,@Nullable TransactionStatus status){//1.创建TransactionInfo
TransactionInfo txInfo =newTransactionInfo(tm, txAttr, joinpointIdentification);if(txAttr != null){//2.设置TransactionStatus// The transaction manager will flag an error if an incompatible tx already exists.
txInfo.newTransactionStatus(status);}else{//2.记录日志,省略...}//3.事物信息和线程绑定
txInfo.bindToThread();return txInfo;}privatevoidbindToThread(){// Expose current TransactionStatus, preserving any existing TransactionStatus// for restoration after this transaction is complete.this.oldTransactionInfo = transactionInfoHolder.get();
transactionInfoHolder.set(this);}
publicfinalvoidcommit(TransactionStatus status)throws TransactionException {//1.已经完成的不能再提交,抛出异常if(status.isCompleted()){thrownewIllegalTransactionStateException("Transaction is already completed - do not call commit or rollback more than once per transaction");}
DefaultTransactionStatus defStatus =(DefaultTransactionStatus) status;//2.此时说明外层已经抛出异常,那么就回滚if(defStatus.isLocalRollbackOnly()){processRollback(defStatus,false);return;}//3.处理回滚的情况if(!shouldCommitOnGlobalRollbackOnly()&& defStatus.isGlobalRollbackOnly()){if(defStatus.isDebug()){
logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");}processRollback(defStatus,true);return;}//4.提交processCommit(defStatus);}