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