项目开发-iBatis事务源码之事务提交和回滚

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wojiushiwo945you/article/details/45055903

     接上篇继续事务的提交和结束流程如下。

   commitTransaction 

     SqlMapClientImpl的commitTransaction操作,类似startTransaction,是最终由SqlMapExecutorDelege的commitTransaction完成的。

  /**
   * Commit the transaction on a session
   *
   * @param sessionScope - the session
   * @throws SQLException - if the transaction could not be committed
   */
  public void commitTransaction(SessionScope sessionScope) throws SQLException {
    try {
      // Auto batch execution
      if (sessionScope.isInBatch()) {
        executeBatch(sessionScope);
      }
      sqlExecutor.cleanup(sessionScope);
      txManager.commit(sessionScope);
    } catch (TransactionException e) {
      throw new NestedSQLException("Could not commit transaction.  Cause: " + e, e);
    }
  }
       TransactionManager的commit

  public void commit(SessionScope sessionScope) throws SQLException, TransactionException {
    Transaction trans = sessionScope.getTransaction();
    TransactionState state = sessionScope.getTransactionState();
    if (state == TransactionState.STATE_USER_PROVIDED) {
      throw new TransactionException("TransactionManager could not commit.  " +
          "A user provided connection is currently being used by this session.  " +
          "You must call the commit() method of the Connection directly.  " +
          "The calling .setUserConnection (null) will clear the user provided transaction.");
    } else if (state != TransactionState.STATE_STARTED && state != TransactionState.STATE_COMMITTED ) {
      throw new TransactionException("TransactionManager could not commit.  No transaction is started.");
    }
    System.out.println("hello:"+(sessionScope.isCommitRequired() || config.isForceCommit()));
    if (sessionScope.isCommitRequired() || config.isForceCommit()) {
      trans.commit();
      sessionScope.setCommitRequired(false);
    }
    sessionScope.setTransactionState(TransactionState.STATE_COMMITTED);
  }
     Transaction的commit

  public void commit() throws SQLException, TransactionException {
    if (connection != null) {
      connection.commit();
    }
  }

     事务提交操作执行完成后,事务状态被置为提交状态,有增删改操作时,commitRequired标识为真;如果没有异常的话,那么当前SessionScope的SQL操作都被提交。

   endTransaction

    类似startTransaction,都是转发给SqlMapExecutorDelegate的endTransaction。

  /**
   * End the transaction on a session
   *
   * @param sessionScope - the session
   * @throws SQLException - if the transaction could not be ended
   */
  public void endTransaction(SessionScope sessionScope) throws SQLException {
    try {
      try {
        sqlExecutor.cleanup(sessionScope);
      } finally {
        txManager.end(sessionScope);
      }
    } catch (TransactionException e) {
      throw new NestedSQLException("Error while ending transaction.  Cause: " + e, e);
    }
  }
   TransactionManager的end

  public void end(SessionScope sessionScope) throws SQLException, TransactionException {
    Transaction trans = sessionScope.getTransaction();
    TransactionState state = sessionScope.getTransactionState();

    if (state == TransactionState.STATE_USER_PROVIDED) {
      throw new TransactionException("TransactionManager could not end this transaction.  " +
          "A user provided connection is currently being used by this session.  " +
          "You must call the rollback() method of the Connection directly.  " +
          "The calling .setUserConnection (null) will clear the user provided transaction.");
    }

    try {
      if (trans != null) {
        try {
          if (state != TransactionState.STATE_COMMITTED) {
            if (sessionScope.isCommitRequired() || config.isForceCommit()) {
              trans.rollback();
              sessionScope.setCommitRequired(false);
            }
          }
        } finally {
          sessionScope.closePreparedStatements();
          trans.close();
        }
      }
    } finally {
      sessionScope.setTransaction(null);
      sessionScope.setTransactionState(TransactionState.STATE_ENDED);
    }
  }

      事务的提交操作会根据当前SessionScope的事务信息判断是否需要回滚,只有当前事务状态为非提交状态,同时,提交标识为真时,才会调用Transaction的rollback操作。在两种情况下会出现SQL的回滚:

      第一种,在MappedStatement的executeUpdate操作中,会设置事务的提交标识为真,并且只有在正确执行完成SQL后才会设置事务状态为已提交状态。如果整个流程中出现异常,那么这条SQL就会回滚。

      第二种,用户执行了startTransaction,但是没有调用commitTransaction方法,那么这期间的SQL都会回滚。

      Finally分支中会关闭所有的JDBC语句已经Connection,并设置事务状态为结束状态。至此,一次完整的SQL执行结束。
展开阅读全文

没有更多推荐了,返回首页