`
penggle
  • 浏览: 58489 次
  • 性别: 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[]是什么呢

相关推荐

    解决mybatis-plus3.1.1版本使用lambda表达式查询报错的方法

    错误日志显示的是一个`MybatisPlusException`,提示“Your property named 'username' cannot find the corresponding database column name!”,这意味着MyBatis-Plus在尝试映射Java对象的属性(如`username`)到...

    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;

    mybatis中批量插入的两种方式(高效插入)

    需要注意的是,使用`ExecutorType.BATCH` 模式时,由于批处理特性,事务提交前无法获取到自增ID,这可能在某些业务场景下不适用。因此,需要根据实际需求来选择合适的执行器类型。 总结来说,MyBatis 通过`foreach`...

    mybatis-cursor-demo.zip

    使用Cursor的关键在于调用`selectList`方法时传入`ExecutorType.SIMPLE`或`ExecutorType.BATCH`,并确保返回值类型是`List`的子类,比如`ArrayList`或`LinkedList`,这样MyBatis就会自动启用Cursor模式。 以下是一...

    Mybatis插件机制详解

    1. **Executor**:通过`newExecutor(Transaction transaction, ExecutorType executorType)`方法创建。其中`ExecutorType`定义了不同的执行策略,如批量更新等。 2. **StatementHandler**:由`Executor`内部创建并...

    mybatis批量添加数据的方法1

    MyBatis批量添加数据的方法 ...使用Session的ExecutorType可以批量添加大量数据,但它需要在Java代码中编写循环语句来添加数据,且需要手动提交事务。 选择哪种方法取决于具体的业务需求和性能要求。

    mybaits demo程序

    - MyBatis允许在XML映射文件中编写条件语句,如`if`、`choose`(when/otherwise)、`where`、`trim`等标签,可以根据变量值动态生成SQL,避免了大量字符串拼接导致的性能问题。 4. **结果映射**: - 结果映射用于...

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

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

    mybatis-spring-1.3.1

    5. **ExecutorType**: 在MyBatis-Spring中,可以通过Spring的事务配置来指定ExecutorType(执行器类型),如SIMPLE、REUSE或BATCH,这使得在Spring环境下也可以灵活调整MyBatis的执行策略。 6. **Paging Support**:...

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

    超出打开游标的最大数的原因和解决方案 在 Oracle 数据库中,游标(cursor)是一种临时工作区,用于存储查询结果。每个会话可以打开多个游标,但存在一个限制,即 OPEN_CURSORS 参数指定的最大游标数。...

    基于Spring+Ibatis的安全线程实现

    6. **iBatis的ExecutorType**:在iBatis中,ExecutorType.SIMPLE是最基础的执行器,每个Statement操作都会创建一个Statement对象;ExecutorType.REUSE可以复用Statement,提高性能;ExecutorType.BATCH则适合批量...

    MyBatis批量添加数据2种实现方法

    今天,我们将介绍两种实现批量添加数据的方法,分别是:通过foreach标签拼接SQL语句和基于Session的ExecutorType进行批量添加。 方法一:通过foreach标签拼接SQL语句 在MyBatis中,我们可以使用foreach标签来拼接...

    MyBatis

    至于标签“工具”,MyBatis提供了一些辅助工具类,如ExecutorType(执行器类型)用于设置批处理或简单执行,ParameterHandler(参数处理器)用于处理参数,ResultSetHandler(结果集处理器)负责将数据库结果转化为...

    源码分析专题之Mybatis课程一之源码分析与实现2

    例如,动态 SQL 通过 `if`, `choose`, `when`, `otherwise` 等标签实现,缓存分为本地缓存和二级缓存,而事务控制则涉及到 TransactionFactory 和 ExecutorType。 5. **mybatis-spring-x.x.x.jar** MyBatis 与 ...

    对mybatis3 基本环境搭建优化(二)

    1. **配置文件优化**:在`mybatis-config.xml`中,可以设置默认的ExecutorType为`BATCH`或`REUSE`以提高性能,避免每次都创建新的Statement。 2. **日志配置**:根据开发阶段选择合适的日志实现,如Log4j、Logback...

    ibatis2.X升级mybatis3.X之曲径通幽处

    例如,`&lt;if&gt;`、`&lt;choose&gt;`、`&lt;when&gt;`、`&lt;otherwise&gt;`等标签的使用,让SQL语句可以根据条件动态生成,提高了代码的复用性和灵活性。 在映射器接口方面,Mybatis3.x允许开发者直接在接口方法上使用@Select、@Insert、...

    MyBatis 3.5.9 官方html文档 包含MyBatis-Spring插件官方文档

    7. **ExecutorType**:MyBatis提供了三种执行器类型:SIMPLE(默认,每个语句都会开启新的事物并执行)、REUSE(复用已经存在的SqlSession,减少创建和关闭SqlSession的开销)、BATCH(批量操作,适用于大量插入、...

    MyBatis 源码分析 之SqlSession接口和Executor类

    例如,ExecutorType.BATCH对应BatchExecutor,适用于批处理操作,而ExecutorType.SIMPLE和ExecutorType.REUSE则分别对应简单的执行和重用预编译语句的执行器。 总的来说,SqlSession接口和Executor类在MyBatis中...

    06.2、框架—其他(12题)1

    利用ExecutorType.BATCH执行器,创建SqlSession时指定ExecutorType为BATCH,这样可以将多条SQL语句放入批处理,最后调用commit()提交,如果出现异常则rollback()回滚,确保事务一致性。 6. Session机制: Session...

    mybatis使用拦截器实现分页操作

    除了上述基本的实现方式,还可以考虑结合MyBatis的`ExecutorType.SIMPLE`或`ExecutorType.BATCH`执行器,以及`boundSql`对象来优化分页性能。例如,可以避免在`SIMPLE`模式下对每个分页请求都进行数据库连接的创建和...

Global site tag (gtag.js) - Google Analytics