jdbc - 使用连接池一段时间后自动将更改提交为 TRUE

标签 jdbc connection-pooling

我遇到了一些奇怪的问题。

我使用池来创建和管理数据库连接,我将 DefaultAutocommit 选项设置为 FALSE

但是过了一段时间,当发生错误并调用 rollback 时,会抛出异常:Can't call rollback when autocommit=true

重新启动 JBoss 将解决问题,因为将创建新的数据源。

这是我创建数据源的方法:

protected DataSource getDataSource(String driverClassName, String dbUrl, String dbUser, String dbPwd) {
    PoolProperties poolProperties = new PoolProperties();
    poolProperties.setUrl(dbUrl);
    poolProperties.setDriverClassName(driverClassName);
    poolProperties.setUsername(dbUser);
    poolProperties.setPassword(dbPwd);

    poolProperties.setDefaultAutoCommit(false);
    poolProperties.setTestWhileIdle(false);
    poolProperties.setTestOnBorrow(true);
    poolProperties.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
    poolProperties.setValidationQuery("SELECT 1");
    poolProperties.setTestOnReturn(false);
    poolProperties.setLogAbandoned(false);
    poolProperties.setRemoveAbandoned(true);
    poolProperties.setRemoveAbandonedTimeout(20);
    poolProperties.setMaxActive(100);
    poolProperties.setInitialSize(10);
    poolProperties.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");

    return new DataSource(poolProperties);
}

以及我如何获得连接:

xxx.getDataSource().getConnection();

我还没有尝试,但我的第一个调用将是使用 setAutoCommit(false) 直接在连接上强制自动提交。

虽然我不明白为什么poolProperties.setDefaultAutoCommit(false);停止执行这项工作。

堆栈跟踪:

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Can't call rollback when autocommit=true
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
    at com.mysql.jdbc.Util.getInstance(Util.java:384)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:929)
    at com.mysql.jdbc.ConnectionImpl.rollback(ConnectionImpl.java:4805)
    at sun.reflect.GeneratedMethodAccessor302.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:125)
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:94)
    at org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:71)
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:94)
    at org.apache.tomcat.jdbc.pool.interceptor.ConnectionState.invoke(ConnectionState.java:140)
    at $Proxy333.rollback(Unknown Source)

最佳答案

这就是今天的情况,我在池创建的每个连接上强制使用 AutoCommit 属性。

这是可行的,所以它肯定可能是池类的错误。

编辑: 我还遇到了事务隔离的问题,该问题以相同的方式设置,但没有考虑在内。经过一番研究,我发现这可能与我使用的 Mysql 连接器/J 有关( http://dev.mysql.com/doc/refman/5.1/en/connector-j-reference-configuration-properties.html )。

我在文档中发现了这个有趣的参数:

useLocalSessionState

Should the driver refer to the internal values of autocommit and transaction isolation that are set by Connection.setAutoCommit() and Connection.setTransactionIsolation() and transaction state as maintained by the protocol, rather than querying the database or blindly sending commands to the database for commit() or rollback() method calls?

默认值: false

关于jdbc - 使用连接池一段时间后自动将更改提交为 TRUE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11392090/

相关文章:

java - Spring Boot WS 和 JDBC 的对象名称无效 'INFORMATION_SCHEMA.SEQUENCES'

jdbc - 当连接返回到池时,BoneCP(或任何其他池)是否关闭连接的语句?

java - [警告][插件]插件 jdbc- River,无法调用自定义 onModule 方法

java - 用于从数据库检索值的批处理语句执行的最佳替代方案是什么(MSSQL 2008)

jdbc - JDBC 的 Connection.isClosed() 有什么用,为什么 Snaq DBPool 在关闭时行为不端?

sql-server - Tomcat 6 中的 SQL Server 连接管理

tomcat - getConnection() 和 getConnection(String username, String password) 之间的区别

postgresql - 重新启动 postgres 后使用 Grails 自动重新连接到 postgres

asp.net - ODP.NET 连接池问题 - 数据库宕机后的容错

java - SQL 根据条件将变量字符串附加到 WHERE 子句