通过前几篇幅对mybatis的执行过程代码的分析,发现【sql拦截器来统计耗时能包含获取数据库连接的时间】这个观点是有误差的!
如果是非事务的sql确实是包含数据库连接时间,但带事务处理会提前开启连接。

常规流程

执行过程 Mapper.update -> MapperProxy - MapperMethod -> SqlSessionTemplete -> sqlSessionProxy-> SqlSessionInterceptor -> Executor -> StatementHandler -> Statement

  1. 对于每一个Mapper都会通过MapperFactoryBean来生成一个handler是MapperProxy的代理对象。
  2. Configuration、SqlSession、Executor、StatementHandler真的很重要!
  3. 在dao调用方法时,转到MapperProxy调用MapperMethod来选择调用方式,再用 SqlSessionTemplate实例中的sqlSessionProxy来执行。 在执行时会进入sqlSessionProxy的处理handler: SqlSessionInterceptor ;
  4. SqlSessionInterceptor在开启sqlSession<DefaultSqlSession>的过程中,通过SpringManagedTransactionFactory构建的SpringManagedTransaction置入具体执行的executor中,此时在Transaction中Connection是null。通过Plugin来织入executor对自定义interceptor的代理。
  5. 再执行DefaultSqlSession的dml方法实际上是执行executor的dml方法,此时executor是代理类,优先执行代理切面方法<interceptor>, 后续执行SimpleExecutor。
  6. SimpleExecutor在doUpdate、doQuery中,会构建prepareStatement。此时要获取Connection。通过Executor中存入的SpringManagedTransaction获取连接时,将判定是否为null(如果是事务则不会为空),是则开启一个新的连接。
  7. 当执行完毕时,SqlSessionInterceptor执行closeSqlSession方法: 
    1. 无事务则直接关闭连接了!!
      session.close()->executor.close->SpringManagedTransaction.close->DataSourceUtils.releaseConnection->DataSourceUtils.doCloseConnection
    2. 在有事务的情况下只执行到了SqlSessionHolder.released(): referenceCount--;

带事务的执行过程:

  1. @Transactional (TransactionInterceptor)处理: 见 TransactionAspectSupport.invokeWithinTransaction
    首先获取配置的事务管理器 PlatformTransactionManager(实例DataSourceTransactionManager)、及joinpointIdentification,  在createTransactionIfNecessary中构建TransactionInfo信息与当前线程绑定在ThreadLocal中, 此过程会通过DataSource.getConnection生成了一个connection实例封装在ConnectionHolder中,与DataSource 作为值对绑定在当前线程上。再回到【常规流程的步骤3】。 此时在SpringManagedTransaction真正需要获取connection时,会从线程上下文中获取到。
  2. 当全部执行完后,回到TransactionAspectSupport执行commitTransactionAfterReturning。 beforeCompletion() 会  clearLocalCache() -> flushStatements(true)- >ConnectionHolder.released(), 当最终提交doCommit(Connection.commit())后才会doCloseConnection。 无论是在sql执行还是在commit阶段如果抛出异常则回滚。
    mybatis(5) - 总结-LMLPHPmybatis(5) - 总结-LMLPHP
02-15 18:40