`
penggle
  • 浏览: 57888 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Cannot change the ExecutorType when there is an existing transaction

阅读更多
但凡使用mybatis,同时与spring集成使用时,接下来要说的这个问题是躲不了的。众所周知,mybatis的SqlSessionFactory在获取一个SqlSession时使用默认Executor或必须要指定一个Executor,这样一来,在同一个SqlSession的生命周期中,要想切换Executor是不可能的,比如在一个复杂业务中:
sqlSession.insert("insertMainOrder", mainOrder); // -----(1)

for(OrderInfo childOrder : childOrderList){      // -----(2)
    sqlSession.insert("insertChildOrder", childOrder);
}

如果sqlSession使用ExecutorType.SIMPLE open出来的话,(2)处如果是用Jdbc batch操作将是不可能的,当然(2)处如果你再新open一个ExecutorType.BATCH的新的SqlSession的话:A、如果整个业务在无事务环境下运行的话,则不会报错,但是底层会使用多个不同的Connection,浪费资源,最重要的是无法保持在同一个事务中。B、如果整个业务在一个事务中运行的话(如propagation=Propagation.REQUIRED),则会在mybatis-spring框架中报错:TransientDataAccessResourceException("Cannot change the ExecutorType when there is an existing transaction"),究其原因是因为在mybatis-spring框架中在有事务情况下SqlSession是通过sessionFactory与当前线程绑定的,新open出来的SqlSession会与上一个使用的SqlSession的ExecutorType进行比较,如果ExecutorType改变了,则直接报错。

针对这个问题,本人基于mybatis、mybatis-spring框架基础上,通过继承扩展,解决了这个问题。

扩展后,也经过了一些测试,非常成功,得到了预期的结果:
1、一个完整复杂业务中从头到尾使用同一个SqlSession,使用jdbc batch操作(ExecutorType=BATCH)和非batch的普通操作(ExecutorType=SIMPLE)混搭的模式
2、修改过后测试了mybatis事务、spring事务等均符合预期

项目地址:https://github.com/penggle/mybatis-ex
该项目已经发布到maven中央库上:
maven:
      <groupId>com.github.penggle</groupId>
      <artifactId>mybatis-ex</artifactId>
      <version>1.0.0</version>
      <name>mybatis-ex</name>
gradle:
      compile("com.github.penggle:mybatis-ex:1.0.0")
分享到:
评论
1 楼 pulongwang 2015-06-25  
请教下,这个batchInsert、batchUpdate,batchDelete怎么返回结果int[]都是等于空或-2,实际上数据库已经更新了。你测试代码返回的int[]是什么呢

相关推荐

    MySQL创建存储过程批量插入10万条数据

    MySQL创建存储过程批量插入10万条数据 存储过程 ...start TRANSACTION; while i &lt;= args DO insert into A_student(id,name) VALUES (i, concat(“陈瓜皮-”, i)); set i = i+1; end while; COMMIT;

    超出打开游标的最大数的原因和解决方案

    本文对ORA-01000_maximum_open_cursors_exceeded_超出打开游标的最大数的原因和解决方案有详细描述

    前端-后端java的Util类的工具类

    卷 文档 的文件夹 PATH 列表 卷序列号为 000C-BB91 E:. │ config.properties │ Dao.java │ GeneratorDemo.java │ hibernate.cfg.xml │ HibernateDaoImpl.java │ HibernateSessionFactory.java ...

    mybatis:mybatis源码阅读

    3.3.1版本后ExecutorType为简单,重复使用批量插入可以正确返回生成主键 密钥生成器 useGeneratedKeys为true使用Jdbc3KeyGenerator selectKey节点使用SelectKeyGenerator 拦截器 拦截器pluginAll作用于Executor,...

    mybatis-SourceCode:MyBatis原始码学习

    创建SqlSession DefaultSqlSessionFactory(类):实现SqlSessionFactory,交替sqlSession工厂类创建SqlSession,TransactionFactory,关闭事务等可自定义ExecutorType(执行器类型)/事务隔离界别/是否自动提交等...

    spring-mybatis-oracle-performance-issue

    通过Spring MyBatis事​​务或通过MyBatis使用ExecutorType.BATCH WIHOUT在xml中为可为空的列指定jdbcType插入Oracle数据库时,性能可能会严重下降并降低200倍甚至更多。 即使在SqlSessionFactory创建过程中将...

Global site tag (gtag.js) - Google Analytics