Skip to content

使用游标+druid数据源,出现java.sql.SQLException: No operations allowed after statement closed. #3530

@zhyuan1

Description

@zhyuan1

About the Bug...

  • I have checked that this issue has not already been reported.

  • I have confirmed this bug exists on the latest version of MyBatis.

  • I have confirmed this bug reproduces without 3rd party extensions (e.g. mybatis-plus).

Database Version

mysql 8.0.30

JDBC Driver Version

mysql-connector 8.0.28 druid1.2.9

Issue Description

代码

try(SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.SIMPLE);
) {
cursor = sqlSession.selectCursor("xxx", queryParam);
//数据处理 省略
}

初步分析:
1、cursor = sqlSession.selectCursor("xxx", queryParam);这一步执行时,会走到SimpleExecutor的doQueryCursor方法,在方法最后会执行stmt.closeOnCompletion(); 当与该 Statement关联的所有 ResultSet都被关闭时,此 Statement将​​自动被关闭​​。
2、代码最后手动关闭sqlSession时,会触发stmt重置,但这时候底层rawStmt已经close。

这里使用MySQL Connector/J 驱动​​提供的StatementImpl.closeOnCompletion()​​资源回收机制。跟druid的资源管理有冲突。麻烦看下是我使用姿势问题还是bug

异常堆栈:

java.sql.SQLException: No operations allowed after statement closed.
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:82)
at com.mysql.cj.jdbc.ServerPreparedStatement.clearParameters(ServerPreparedStatement.java:253)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_clearParameters(FilterChainImpl.java:3433)
at com.alibaba.druid.filter.FilterAdapter.preparedStatement_clearParameters(FilterAdapter.java:1076)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_clearParameters(FilterChainImpl.java:3430)
at com.alibaba.druid.filter.FilterAdapter.preparedStatement_clearParameters(FilterAdapter.java:1076)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_clearParameters(FilterChainImpl.java:3430)
at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.clearParameters(PreparedStatementProxyImpl.java:151)
at com.alibaba.druid.pool.DruidPooledConnection.closePoolableStatement(DruidPooledConnection.java:161)
at com.alibaba.druid.pool.DruidPooledPreparedStatement.close(DruidPooledPreparedStatement.java:201)
at com.alibaba.druid.util.JdbcUtils.close(JdbcUtils.java:98)
at com.alibaba.druid.pool.DruidConnectionHolder.reset(DruidConnectionHolder.java:323)
at com.alibaba.druid.pool.DruidDataSource.recycle(DruidDataSource.java:1951)
at com.alibaba.druid.pool.DruidPooledConnection.recycle(DruidPooledConnection.java:351)
at com.alibaba.druid.filter.FilterChainImpl.dataSource_recycle(FilterChainImpl.java:5049)
at com.alibaba.druid.filter.FilterAdapter.dataSource_releaseConnection(FilterAdapter.java:2750)
at com.alibaba.druid.filter.FilterChainImpl.dataSource_recycle(FilterChainImpl.java:5045)
at com.alibaba.druid.filter.stat.StatFilter.dataSource_releaseConnection(StatFilter.java:711)
at com.alibaba.druid.filter.FilterChainImpl.dataSource_recycle(FilterChainImpl.java:5045)
at com.alibaba.druid.pool.DruidPooledConnection.syncClose(DruidPooledConnection.java:324)
at com.alibaba.druid.pool.DruidPooledConnection.close(DruidPooledConnection.java:270)
at com.tencent.fit.fmha.sdk.ds.FMHADruidProxyConnection.invoke(FMHADruidProxyConnection.java:56)
at com.tencent.fit.fmha.sdk.ds.FMHADruidProxyConnection.close(FMHADruidProxyConnection.java:150)
at org.springframework.jdbc.datasource.DataSourceUtils.doCloseConnection(DataSourceUtils.java:406)
at org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:393)
at org.springframework.jdbc.datasource.DataSourceUtils.releaseConnection(DataSourceUtils.java:360)
at org.mybatis.spring.transaction.SpringManagedTransaction.close(SpringManagedTransaction.java:115)
at org.apache.ibatis.executor.BaseExecutor.close(BaseExecutor.java:90)
at org.apache.ibatis.executor.CachingExecutor.close(CachingExecutor.java:64)
at org.apache.ibatis.session.defaults.DefaultSqlSession.close(DefaultSqlSession.java:263)

About your report...

  • I did not use images 🖼️ for showing text information (code, error, etc.).

  • I checked the Preview and my report looks awesome! 👍

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions