Spring源码(九)--Transactional注解的源码

avatar
作者
筋斗云
阅读量:0

Transactional代码的方法栈

      at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:256)       at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:378)       at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:474)       at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:289)       at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) 

源码

  • TransactionInterceptor 如下:

org.springframework.transaction.interceptor.TransactionInterceptor#invoke

    @Override     @Nullable     public Object invoke(MethodInvocation invocation) throws Throwable {         // 获取目标类         Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);  	   // 事务处理         return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);     } 
  • TransactionAspectSupport 如下:

org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

这是 Transactional 事务的核心代码,使用了 AOP 。可以重点看看。

包括 :begin(开启事务) 和commit(提交事务)、rollback(回滚事务)

    @Nullable     protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,             final InvocationCallback invocation) throws Throwable {          // 如果事务属性为空,则该方法为非事务性。         TransactionAttributeSource tas = getTransactionAttributeSource();         final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);         final PlatformTransactionManager tm = determineTransactionManager(txAttr);         final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);          if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {             // begin(开启事务)             TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);             Object retVal = null;             try {               // 环绕通知。调用链中的下一个拦截器。并调用目标对象。                 retVal = invocation.proceedWithInvocation();             }             catch (Throwable ex) {                 //如果有异常,就  rollback(回滚事务)                 completeTransactionAfterThrowing(txInfo, ex);                 throw ex;             }             finally {                                cleanupTransactionInfo(txInfo);             }             // commit(提交事务)             commitTransactionAfterReturning(txInfo);             return retVal;         }          else {             final ThrowableHolder throwableHolder = new ThrowableHolder();              // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.             try {                 Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {                     TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);                     try {                         return invocation.proceedWithInvocation();                     }                     catch (Throwable ex) {                         if (txAttr.rollbackOn(ex)) {                             // A RuntimeException: will lead to a rollback.                             if (ex instanceof RuntimeException) {                                 throw (RuntimeException) ex;                             }                             else {                                 throw new ThrowableHolderException(ex);                             }                         }                         else {                             // A normal return value: will lead to a commit.                             throwableHolder.throwable = ex;                             return null;                         }                     }                     finally {                         cleanupTransactionInfo(txInfo);                     }                 });                  // Check result state: It might indicate a Throwable to rethrow.                 if (throwableHolder.throwable != null) {                     throw throwableHolder.throwable;                 }                 return result;             }             catch (ThrowableHolderException ex) {                 throw ex.getCause();             }             catch (TransactionSystemException ex2) {                 if (throwableHolder.throwable != null) {                     logger.error("Application exception overridden by commit exception", throwableHolder.throwable);                     ex2.initApplicationException(throwableHolder.throwable);                 }                 throw ex2;             }             catch (Throwable ex2) {                 if (throwableHolder.throwable != null) {                     logger.error("Application exception overridden by commit exception", throwableHolder.throwable);                 }                 throw ex2;             }         }     } 
  • createTransactionIfNecessary :

方法路径: org.springframework.transaction.interceptor.TransactionAspectSupport#createTransactionIfNecessary

必要时根据给定的TransactionAttribute创建事务。

    /**      * 必要时根据给定的TransactionAttribute创建事务。      * 允许调用者通过TransactionAttributeSource执行自定义TransactionAttribute查找。      */     @SuppressWarnings("serial")     protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,             @Nullable 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);     } 
  • getTransaction 源码:

方法路径: org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction

获取事务。

    @Override     public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {         Object transaction = doGetTransaction();          // Cache debug flag to avoid repeated checks.         boolean debugEnabled = logger.isDebugEnabled();          if (definition == null) {             // 如果没有给出事务定义,则使用默认值             definition = new DefaultTransactionDefinition();         }          if (isExistingTransaction(transaction)) {             // 如果是已有的事务,就会检查传播行为以找出行为方式。             return handleExistingTransaction(definition, transaction, debugEnabled);         }          // Check definition settings for new transaction.         if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {             throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());         }          // No existing transaction found -> check propagation behavior to find out how to proceed.         if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {             throw new IllegalTransactionStateException(                     "No existing transaction found for transaction marked with propagation 'mandatory'");         }         else if (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);                 DefaultTransactionStatus status = newTransactionStatus(                         definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);                 doBegin(transaction, definition);                 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);             return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);         }     }  
  • doGetTransaction :

方法路径: org.springframework.jdbc.datasource.DataSourceTransactionManager#doGetTransaction

    @Override     protected Object doGetTransaction() {         DataSourceTransactionObject txObject = new DataSourceTransactionObject();         txObject.setSavepointAllowed(isNestedTransactionAllowed());         ConnectionHolder conHolder =                 (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());         txObject.setConnectionHolder(conHolder, false);         return txObject;     } 
  • doBegin 设置事务隔离级别:

方法路径: org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin

    /**      * 设置事务隔离级别,忽略超时。      */     @Override     protected void doBegin(Object transaction, TransactionDefinition definition) {         DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;         Connection con = null;          try {             if (!txObject.hasConnectionHolder() ||                     txObject.getConnectionHolder().isSynchronizedWithTransaction()) {                 Connection newCon = obtainDataSource().getConnection();                 if (logger.isDebugEnabled()) {                     logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");                 }                 txObject.setConnectionHolder(new ConnectionHolder(newCon), true);             }              txObject.getConnectionHolder().setSynchronizedWithTransaction(true);             con = txObject.getConnectionHolder().getConnection();              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);                 if (logger.isDebugEnabled()) {                     logger.debug("Switching JDBC Connection [" + con + "] to manual commit");                 }                 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()) {                 TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());             }         }          catch (Throwable ex) {             if (txObject.isNewConnectionHolder()) {                 DataSourceUtils.releaseConnection(con, obtainDataSource());                 txObject.setConnectionHolder(null, false);             }             throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);         }     }  

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!