mybatis / spring

Spring integration for MyBatis 3

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unexpected exception when MySQL sessions reconnected.

doublesong opened this issue · comments

Mybaits version: 2.0.1
MySQL connector version: 8.0.20
**JDBC URL:**jdbc:mysql://io:port/dbname?user=xxx&password=xxx&autoReconnect=ture

When the connection is disconnected and reconnected automatically,we will get unexpected exception:ConnectionImpl.commit, throw exception: Can't call commit when autocommit=true

The stack information is as follows:

ConnectionImpl.commit called, print stackTrace: 
 com.mysql.cj.jdbc.ConnectionImpl.commit(ConnectionImpl.java:773)
 sun.reflect.GeneratedMethodAccessor839.invoke(Unknown Source)
 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 java.lang.reflect.Method.invoke(Method.java:498)
 org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:131)
 org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109)
 org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:79)
 org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109)
 org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:79)
 org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109)
 org.apache.tomcat.jdbc.pool.interceptor.ConnectionState.invoke(ConnectionState.java:158)
 org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109)
 org.apache.tomcat.jdbc.pool.TrapException.invoke(TrapException.java:39)
 org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109)
 org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:79)
 org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109)
 org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:81)
 com.sun.proxy.$Proxy137.commit(Unknown Source)
 org.mybatis.spring.transaction.SpringManagedTransaction.commit(SpringManagedTransaction.java:101)
 org.apache.ibatis.executor.BaseExecutor.commit(BaseExecutor.java:244)
 org.apache.ibatis.executor.CachingExecutor.commit(CachingExecutor.java:119)
 org.apache.ibatis.session.defaults.DefaultSqlSession.commit(DefaultSqlSession.java:223)
 org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(**SqlSessionTemplate.java:437**)
 com.sun.proxy.$Proxy138.selectList(Unknown Source)
 org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:230)
 com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForMany(MybatisMapperMethod.java:158)
 com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:76)
 com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:62)
 com.sun.proxy.$Proxy184.findByReveAr(Unknown Source)
 com.xxx.xxxx.xx.xxx.dao.xxx.xxx(xxx.java:188)

To avoid this Unexpected exception,We suggets check the connection status before sqlSession.commit method.

 SqlSessionTemplate.java:437
 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);
        }

Guess it might be due to TransactionSynchronizationManager.unbindResource method deregister the session created by auto_reconnect from TransactionManager(is it related to #18 ? )

but the new session reuse old session structure ,is still live in connection pool and isautocommit=true

then mybatis get this session and execute some sql , isSqlSessionTransactional function evaluates this session doesn't belong to spring TransactionManager.
so mybatis run sqlSession.commit method cause this exception

image

Here is SpringTransactionManagerTest's test case. Maybe the exception is original expectations
1676109006567