myBatis 切换数据源(spring事务)理解

摘要:
=null&&unpackedstanceofPersistenceException){//如果未加载转换器,则释放连接以取消锁定。请参阅问题#22关闭sqlSession(sqlSession,SqlSessionTemplate.this.sqlSessionFactory);sqlSession=null;Throwabletranslated=SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException)unpacked);if(translated!=null){unpacked=translated;}throwunwrapped;}最后{if(sqlSession!

1. mybatis (SqlSessionTemplate)的动态代理

  a) sqlSession的结构

  myBatis 切换数据源(spring事务)理解第1张

  b)SqlSession 结构

public class SqlSessionTemplate implements SqlSession {
  //代理对象 ------1
  private final SqlSession sqlSessionProxy;
  /**
   *//构造方法 --------2
   */
  public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
      PersistenceExceptionTranslator exceptionTranslator) {
    //利用jdk的动态代理,生成sqlSessionProxy的代理对象--------3
    this.sqlSessionProxy = (SqlSession) newProxyInstance(
        SqlSessionFactory.class.getClassLoader(),
        new Class[] { SqlSession.class },
        new SqlSessionInterceptor());
  }

  /**
   */
  @Override
  public <T> T selectOne(String statement) {
    //代用代理对象的目标方法,触发代理对象的产生---------4
    return this.sqlSessionProxy.<T> selectOne(statement);
  }

  /**
   */
  private class SqlSessionInterceptor implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      SqlSession sqlSession = getSqlSession(
          SqlSessionTemplate.this.sqlSessionFactory,
          SqlSessionTemplate.this.executorType,
          SqlSessionTemplate.this.exceptionTranslator);
      try {
        //代理对象执行,实际上执行的是sqlSession的目标方法,proxy没有执行--------5
        Object result = method.invoke(sqlSession, args);
        if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
          // force commit even on non-dirty sessions because some databases require
          // a commit/rollback before calling close()
          sqlSession.commit(true);
        }
        return result;
      } catch (Throwable t) {
        Throwable unwrapped = unwrapThrowable(t);
        if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
          // release the connection to avoid a deadlock if the translator is no loaded. See issue #22
          closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
          sqlSession = null;
          Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);
          if (translated != null) {
            unwrapped = translated;
          }
        }
        throw unwrapped;
      } finally {
        if (sqlSession != null) {
          closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
        }
      }
    }
  }

} 

2.没有事务:切换数据源(成功切换数据源)

  a)代理对象执行目标时,切换数据源时 (栈结构)

myBatis 切换数据源(spring事务)理解第2张 

  b) 在DataSourceUtils 中,判断conHolder是否为空,

myBatis 切换数据源(spring事务)理解第3张

3.存在事务:切换数据源(不会切换数据源)

  a)  在执行目标方式时,被spring拦截,检查是否存在事务,(存在事务,调用doBegin方法,为事务准备链接conncetion)

 myBatis 切换数据源(spring事务)理解第4张

  b) 代理对象sqlSessionTemple 执行目标方法中,在DataSourceUtils 中判断connection 已经存在,则直接拿取

myBatis 切换数据源(spring事务)理解第5张

免责声明:文章转载自《myBatis 切换数据源(spring事务)理解》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Android Studio NDK开发入门.NET 程序内存占用问题下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

mybatis学习 十四 resultMap标签 一对一(联合查询)

1.使用 resultMap 实现关联单个对象(联合查询方式) <resultMap type="Student" id="stuMap1"> <id column="sid" property="id"/> <result column="sname" property="name"/> <...

SpringBoot使用MyBatis-Generator详解-copy

SpringBoot使用MyBatis-Generator详解MyBatis-Generator简介MyBatis-Generator使用添加maven依赖创建MBG配置文件运行MBG,生成底层类数据库查询 前几天工作中接触到MyBatis-Generator,发现其方便之处,MyBatis-Generator可以帮助我们实现数据库繁复的增删改查操作,当数...

MyBatis(十一) 嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则

(1)接口中编写方法 public Dept getDeptPlusById(Integer id); (2)Mapper文件 1   <resultMap type="com.eu.bean.Dept" id="MyPlus"> 2 <id column="id" property="id"/> 3...

mybatis 关联查询如何

关联查询: 有job表 和 recruitment表  ,job表有个recruitment_id 字段 与 recruitment 表关联 job表结构 recruitment 表结构:    Job.java @Data @Table(name = "t_job") public class Job{ /** * */...

mybatis中的智能标签之二

智能标签foreach-Array, 智能标签foreach-List数据组,智能标签 foreach list自定义类型接口: /** * 智能标签foreach-Array * @param num * @return */public List<Student> findByForeachArray(int[] num);/** * 智能...

mybatis学习 十一 缓存

1. 应用程序和数据库交互的过程是一个相对比较耗时的过程2. 缓存存在的意义:让应用程序减少对数据库的访问,提升程序运行效率3. MyBatis 中默认 SqlSession 缓存(一级缓存)开启   同一个 SqlSession 对象调用同一个<select>时,只有第一次访问数据库,第一次之后把查询结果缓存到 SqlSession 缓存区(...