屯昌网站建设,wap网站搭建,阿里巴巴域名,文字设计图片在线生成一、问题描述场景描述#xff1a;有这样一个service方法#xff0c;调用了两个dao中的方法。第一个方法按照传入的id批量更新用户名。第二个dao方法无数据库操作#xff0c;仅仅抛出一个RuntimeException.这个service方法通过xml配置由spring事务管理的。两个DAO类中分别有S…一、问题描述场景描述有这样一个service方法调用了两个dao中的方法。第一个方法按照传入的id批量更新用户名。第二个dao方法无数据库操作仅仅抛出一个RuntimeException.这个service方法通过xml配置由spring事务管理的。两个DAO类中分别有SqlSessionTemplate类型的属性template使用IOC的方式注入的。public void batchUpdate() {String usernamenewname59;List idListArrays.asList(10000,10001);userDao.batchUpdateUsername(username, idList);testDao.testException();userDao.batchUpdateUserage(55, idList);testDao.testNormal();}当userDao及testDao中注入的是ExcutorType.Simple类型的template时批量更新用户名的操作会回滚。当userDao及testDao中注入的是ExcutorType.Batch类型的template时批量更新用户名的操作未回滚。经过检查数据库日志发现第二种情况的数据库执行序列如下1 set autocommit 02 rollback3 update t_user set usernamenewname59 where id 100004 update t_user set usernamenewname59 where id 100015 set autocommit 1更新操作在回滚之后执行故回滚失败。调试源代码发现有如下序列AbstractPlatformTransactionManagerprocessRollback () -- triggerAfterCompletion() -- invokeAfterCompletion()--TransactionSynchronizationUtilsinvokeAfterCompletion()--SqlSessionUtilsafterCompletion()--DefaultSqlSessionclose()--BaseExecutorclose() -- rollback() -- flushStatement()--BatchExecutordoFlushStatements()这时就执行了sql语句。简单来说抛出异常spring事务回滚清理资源关闭sqlSession.mybatis关闭sqlsession,关闭前先flushStatements执行未执行的sql语句然后再rollback.但是这个rollback方法里判断connection是受事务管理的就不执行任何操作。public void rollback(boolean required) throws SQLException {if (!closed) {try {clearLocalCache();flushStatements();} finally {if (required) {transaction.rollback();}}}}public void rollback() throws SQLException {if (!this.isConnectionTransactional) {if (this.logger.isDebugEnabled()) {this.logger.debug(Rolling back JDBC Connection [ this.connection ]);}this.connection.rollback();}}二、解决办法1、在自己的应用程序中写个拦截器。在执行完executor的close()之后由这个拦截器再执行一遍connection.rollback()但从代码的可读性来看会非常的差。2、修改mybatis的bug。修改BaseExecutor的rollback()public void rollback(boolean required) throws SQLException {if (!closed) {try {clearLocalCache();if (!required) {flushStatements();}} finally {if (required) {transaction.rollback();}}}}不知道大家有没有碰到过类似的问题又是通过什么方案解决的呢