美文网首页
mybatis于spring事务结合

mybatis于spring事务结合

作者: 7ee4c95bcc68 | 来源:发表于2020-09-30 14:11 被阅读0次

    mybatis如何和spring的事务结合的

    PlatformTransactionManager (平台)事务管理器

    public interface PlatformTransactionManager {
      // 根据指定的传播行为,返回当前活动的事务或创建一个新事务。
      TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;    
      // 使用事务目前的状态提交事务
      void commit(TransactionStatus status) throws TransactionException;    
      // 对执行的事务进行回滚  
      void rollback(TransactionStatus status) throws TransactionException;    
    }
    

    TransactionDefinition 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则

    TransactionStatus 事务运行状态

    spring对方法加有@Transactional的方法进行拦截

    org.springframework.transaction.interceptor.TransactionInterceptor#invoke
    org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction
    org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin
    protected void doBegin(Object transaction, TransactionDefinition definition) {
      //将 Connection 放入到 TransactionSynchronizationManager
      if (txObject.isNewConnectionHolder()) {
        TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
      }
    }
    

    mybatis中拿到和spring管理的Connection

    // org.apache.ibatis.executor.SimpleExecutor#prepareStatement
    protected Connection getConnection(Log statementLog) throws SQLException {
      //从 SpringManagedTransaction拿到 connection
      Connection connection = transaction.getConnection();
    }
    // org.mybatis.spring.transaction.SpringManagedTransaction#openConnection
    private void openConnection() throws SQLException {
      //从Spring管理的连接中拿到 connection
      this.connection = DataSourceUtils.getConnection(this.dataSource);
    }
    //org.springframework.jdbc.datasource.DataSourceUtils#doGetConnection
    public static Connection doGetConnection(DataSource dataSource) throws SQLException {
        //从TransactionSynchronizationManager拿到数据库连接
            ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.getResource(dataSource);
    }
    

    但是我们知道我们使用mybatis-spring的时候使用了SqlSessionTemplate这里也会进行事务操作比如
    对Mapper代理对象调用进行拦截

    // org.mybatis.spring.SqlSessionTemplate.SqlSessionInterceptor
    private class SqlSessionInterceptor implements InvocationHandler {
      @Override
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //...获取SqlSession
        SqlSession sqlSession = getSqlSession(SqlSessionTemplate.this.sqlSessionFactory,
            SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
        try {
          //调用SqlSession来执行sql
          Object result = method.invoke(sqlSession, args);
          //判断当前sqlSession是否在当前事物当中
          if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
                sqlSession.commit(true);
          }
          return result;
        } catch (Throwable t) {
          //...省略方法
        } finally {
          if (sqlSession != null) {
            closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
          }
        }
      }
    }
    // org.mybatis.spring.SqlSessionUtils#isSqlSessionTransactional
    public static boolean isSqlSessionTransactional(SqlSession session, SqlSessionFactory sessionFactory) {
      SqlSessionHolder holder = (SqlSessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);
      return (holder != null) && (holder.getSqlSession() == session);
    }
    // org.mybatis.spring.SqlSessionUtils#closeSqlSession
    public static void closeSqlSession(SqlSession session, SqlSessionFactory sessionFactory) {
      SqlSessionHolder holder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
      if ((holder != null) && (holder.getSqlSession() == session)) {
        holder.released();
      } else {
        session.close();
      }
    }
    

    相关文章

      网友评论

          本文标题:mybatis于spring事务结合

          本文链接:https://www.haomeiwen.com/subject/dhbuuktx.html