流程
- spring 使用aop来拦截事务,要保证spring 使用的Connection和myabtis的使用是的同一个连接
- 如何保证使用同一个连接?ThreadLocal
- org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin #获取链接,放入到ThreadLocal中
- org.springframework.jdbc.datasource.DataSourceTransactionManager#obtainDataSource
- org.mybatis.spring.transaction.SpringManagedTransaction#openConnection #从ThreadLocal中获取链接
- org.springframework.jdbc.datasource.DataSourceUtils#getConnection
- org.springframework.jdbc.datasource.DataSourceUtils#doGetConnection # 使用的同一个数据源,从当前ThreadLocal中拿到Connection
- org.springframework.transaction.support.TransactionSynchronizationManager#getResource
- org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin #获取链接,放入到ThreadLocal中
- 事务提交
- org.mybatis.spring.transaction.SpringManagedTransaction#commit # 本身不做事务提交,主要isConnectionTransactional这个属性决定的,获取链接时判断当前链接是否带有事务,如果是ture,当commit时则不做事务提交,由 spring 事务管理器提交事务。以下问执行流程
- org.springframework.transaction.interceptor.TransactionAspectSupport#commitTransactionAfterReturning
- org.springframework.transaction.support.AbstractPlatformTransactionManager#processCommit
- org.springframework.transaction.support.AbstractPlatformTransactionManager#triggerBeforeCommit
- org.mybatis.spring.SqlSessionUtils.SqlSessionSynchronization#beforeCommit
- org.apache.ibatis.session.defaults.DefaultSqlSession#commit(boolean)
- org.apache.ibatis.executor.BaseExecutor#commit
- org.mybatis.spring.transaction.SpringManagedTransaction#commit
- org.springframework.transaction.support.AbstractPlatformTransactionManager#triggerBeforeCompletion
- org.springframework.transaction.support.AbstractPlatformTransactionManager#doCommit
- java.sql.Connection#commit
- org.springframework.transaction.support.AbstractPlatformTransactionManager#triggerBeforeCommit
总结
- 多数据源下要保证SqlSessionFactory和DataSourceTransactionManager的数据源用的同一个。
- 如果在原来的事务下再开线程做业务操作,则事务和主线程事务是不同的(连接不同)