读书人

mybatis批量更新的有关问题

发布时间: 2012-10-08 19:54:56 作者: rapoo

mybatis批量更新的问题

转:mybatis批量更新的问题

?

4 update t_user set username="newname59" where id = '10001'
5 set autocommit = 1
更新操作在回滚之后执行,故回滚失败。

调试源代码发现有如下序列:
AbstractPlatformTransactionManager
?processRollback () --> triggerAfterCompletion() --> invokeAfterCompletion()
-->
TransactionSynchronizationUtils
?invokeAfterCompletion()
-->
SqlSessionUtils
??? afterCompletion()
-->
DefaultSqlSession
?close()
-->
BaseExecutor
?close() --> rollback() --> flushStatement()
-->
BatchExecutor
?doFlushStatements()
这时就执行了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();
??????? }
????? }
??? }
? }?

不知道大家有没有碰到过类似的问题,又是通过什么方案解决的呢?

读书人网 >编程

热点推荐