当前位置:Gxlcms > 数据库问题 > Spring Transaction + MyBatis SqlSession事务管理机制研究学习

Spring Transaction + MyBatis SqlSession事务管理机制研究学习

时间:2021-07-01 10:21:17 帮助过:189人阅读

重写了其中的一些方法,具体每个方法的作用,限于篇幅,本文不再赘述,这里《Spring技术内幕》学习笔记16——Spring具体事务处理器的实现有详细的介绍。


     在现有的项目中,我们在public方法上面使用了@Transactional注解,当有线程调用此方法时,Spring会首先扫描到@Transactional注解,进入DataSourceTransactionManager继承自AbstractPlatformTransactionManager的getTransaction()方法,在getTransaction()方法内部,会调用doGetTransaction()方法,@Transactional的注解中,存在一个事务传播行为的概念,即propagation参数,默认等于PROPAGATION_REQUIRED,表示如果当前没有事务,就新建一个事务,如果存在一个事务,方法块将使用这个事务,具体其他参数的意义请看下图:

 

技术分享

 

 在getTransaction方法中,DataSourceTransactionManager重写了isExistingTransaction()方法,用于判断当前是否存在事务,以下是其的源码:

?
1 2 3 4 5 6     @Override     protected boolean isExistingTransaction(Object transaction) {         logger.debug(Thread.currentThread().getName() + ">>>" "DataSourceTransactionManager.isExistingTransaction()");         DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;         return (txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive());     }

    但是,这几天我对源码进行调试的过程中,发现多线程并发的时候,isExistingTransaction方法总是返回的false,即ConnectionHolder总是为空,这是遇到的第一个疑问点,目前还没有弄清楚。由于源码判断当前不存在事务,所以总是会Creating new transaction,即新建一个事务。新建事务之后,会执行重写的doBegin()方法,在doBegin方法中,首先通过下面的代码判断了ConnectionHolder是否为空,如下:

?
1 2 3 4 5 6 7 8 9             if (txObject.getConnectionHolder() == null                     || txObject.getConnectionHolder().isSynchronizedWithTransaction()) {                 Connection newCon = this.dataSource.getConnection();                 if (logger.isDebugEnabled()) {                     logger.debug(Thread.currentThread().getName() + ">>>" "Acquired Connection [" + newCon                             "] for JDBC transaction");                 }                 txObject.setConnectionHolder(new ConnectionHolder(newCon), true);             }

 

这里会从当前配置的数据源中获取一个连接,然后设置相应的ConnectionHolder,接下来是关键的一步,也是存在的第二个问题点,拿到connection后,会首先判断connection的autoCommit属性是否为true,之前工作中在使用原始JDBC的时候,当进行事务的控制时,我们总是会首先设置autoCommit为false,禁止事务自动提交,然后commit提交事务,最后设置autoCommit为true。Spring Transaction也是这样进行管理的,但是问题来了, 先看源码:

 

?
1 2 3 4 5 6 7 8 9 10

人气教程排行