spring--mybatis事務總結


spring--事務原理mybatis--MapperScannerConfigurer 和 mybatis--MapperProxy事務,最近想把spring mybatis中的事務和mapper接口的原理分析分析,陸陸續續寫了些,這篇做個總結。

spring+mybatis mapper接口 聲明式事務配置

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
      lazy-init="false">
    <property name="dataSource" ref="dataSource"/>
    <property name="mapperLocations" value="classpath:sqlmapper/*Mapper.xml"/>
    <property name="plugins">
        <list>
            <bean class="***">
                <property name="dialect">
                    <bean class="***"/>
                </property>
            </bean>
        </list>
    </property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="*.*.*" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>

<bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="do*" read-only="false" rollback-for="java.lang.Exception"/>
            <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="pc" expression="execution(* springtry.web.service.*.*(..))"/>
        <aop:advisor pointcut-ref="pc" advice-ref="txAdvice"/>
    </aop:config>

ps:以上在service層注入事務,do開頭方法傳播機制是required,其它的是supports

1. org.mybatis.spring.SqlSessionFactoryBean解析mapper xml配置,根據namespace添加class mapper組裝Configuration對象,設置它的environment(包含springManagedTransactionFactory),最后getObject()包裝出DefaultSqlSessionFactory;

 

2. org.mybatis.spring.mapper.MapperScannerConfigurer掃描basePackage下的mapper接口,每個接口封裝為MapperFactoryBean(包含封裝了DefaultSqlSessionFactory的SqlSessionTemplate),注冊給spring容器。

ps:當調用"mapper接口"時去DefaultSqlSessionFactory-》Configuration獲得接口類的代理類

MapperProxy mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);

 

3. 前面兩步是系統的前提工作。

從service層方法開始,首先進入TransactionInerceptor事務攔截器,由 DataSourceTransactionManager 生成一個DataSourceTransactionObject事務對象,封裝在DefaultTransactionStatus中,調用doBegin開啟這個事務對象,設置這個事務對象 setConnectionHolder(new ConnectionHolder(Connection ex)),把這個ConnectionHolder 以鍵值對綁定在當前線程上 <this.getDataSource(),txObject.getConnectionHolder()>

TransactionSynchronizationManager.bindResource(this.getDataSource(), txObject.getConnectionHolder());

返回這個 DefaultTransactionStatus對象,封裝在TransactionAspectSupport.TransactionInfo中,綁定在當前線程上,之后調用實際service方法

 

4. service方法中會注入mybatis mapper接口,調用時實際調用

MapperFactoryBean-》SqlSessionTemplate-》DefaultSqlSessionFactory-》Configuration.getMapper(mapper接口, SqlSessionTemplate);

 返回MapperProxy對mapper接口的代理,接着調用MapperProxy

 

5. MapperProxy中,根據調用的Method返回一個MapperMethod對象.execute(SqlSessionTemplate this.sqlSession, args),其中調用sqlSession.insert,           sqlSession.update,sqlSession.delete,sqlSession.selectList,sqlSession.selectMap,sqlSession.selectOne等,

 

6. 接下來調用SqlSessionTemplate的方法,實際調用SqlSessionTemplate.sqlSessionProxy(SqlSessionTemplate.SqlSessionInterceptor攔截器攔截的代理),攔截器中使用 SqlSessionUtils 調用

SqlSessionTemplate.DefaultSqlSessionFactory.openSession-》Configuration-》environment-》springManagedTransactionFactory

生成一個SpringManagedTransaction事務對象,封裝在一個Executor(SimpleExecutor/ReuseExecutor/BatchExecutor)中,封裝在DefaultSqlSession中並返回。

封裝在SqlSessionHolder中,並以鍵值對綁定在當前線程<DefaultSqlSessionFactory,SqlSessionHolder>

SqlSessionUtils 返回DefaultSqlSession

 

7. 調用DefaultSqlSession的(update/select等),其中

MappedStatement e = this.configuration.getMappedStatement(接口名.方法名 statement);

this.executor.query/update

 

8. 回到第6步生成的Executor,doupdate/doquery時會prepareStatement,其中會getConnection調用SpringManagedTransaction事務對象的getConnection(),

DataSourceUtils.getConnection(this.dataSource);

看 mybatis--MapperProxy事務 最后分析的

ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.getResource(dataSource);

使用的是第三步當前線程的鍵值對,也就是service層開啟spring事務的connection

 

其實,神秘的spring事務本質還是jdbc的connection,跟我們直接使用jdbc是一樣的,但是做了增強

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM