Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 由于没有连接而提交失败时的回滚行为_Java_Jdbc_Eclipselink_Rollback_Hikaricp - Fatal编程技术网

Java 由于没有连接而提交失败时的回滚行为

Java 由于没有连接而提交失败时的回滚行为,java,jdbc,eclipselink,rollback,hikaricp,Java,Jdbc,Eclipselink,Rollback,Hikaricp,目前,我们正在使用HikariCP来管理我们的连接池 鉴于下面提到的代码片段,我们面临以下问题: try{ txn.begin(); entityManager.persist(someEntity); txn.commit();// Line 1 } catch(Throwable tx ){ if(txn.isActive()){ txn.rollback(); //Line 2 } } EntityManager尝试提交—为此,它需要来自Hi

目前,我们正在使用HikariCP来管理我们的连接池

鉴于下面提到的代码片段,我们面临以下问题:

try{
    txn.begin(); 
    entityManager.persist(someEntity);
    txn.commit();// Line 1
} catch(Throwable tx ){
   if(txn.isActive()){
    txn.rollback(); //Line 2
   }
}
EntityManager尝试提交—为此,它需要来自HikariCP的连接。Hikari超时,由于我们没有获得任何数据库连接,这导致异常。现在,当尝试回滚事务时,回滚序列会再次尝试获取连接-

  • 如果找不到连接,它将再次失败
  • 如果从池中找到连接,将使用该连接。默认情况下,连接处于autocommit=true模式,因此回滚失败,池将连接标记为断开,因为发生回滚时连接的预期状态为autocommit=0
  • 这很奇怪,因为我们假设回滚应该发生在尝试提交的同一个连接上;如果未找到连接,则不应尝试回滚。然而,事实并非如此。这会导致健康连接被标记为断开,并且每当池中出现压力时,此循环会在大多数API中重复

    我们使用的是EclipseLink版本2.5.2,但即使在最新版本中也存在这个问题。我可以追溯到DatasourceAccessor.java中回滚序列的这一部分:

     public synchronized void incrementCallCount(AbstractSession session) {
        this.callCount++;
    
        if (this.callCount == 1) {
            // If the login is null, then this accessor has never been connected.
            if (this.login == null) {
                throw DatabaseException.databaseAccessorNotConnected();
            }
    
            // If the connection is no longer connected, it may have timed out.
            if (this.datasourceConnection != null) {
                if (shouldCheckConnection && !isConnected()) {
                    if (this.isInTransaction) {
                        throw DatabaseException.databaseAccessorNotConnected();
                    } else {
                        reconnect(session);
                    }
                }
            } else {
                // If ExternalConnectionPooling is used, the connection can be re-established.
                if (this.usesExternalConnectionPooling) {
                    reconnect(session); //Why reconnect?
                    session.postAcquireConnection(this);
                    currentSession = session;
                } else {
                    throw DatabaseException.databaseAccessorNotConnected();
                }
            }
        }
    }
    
    执行回滚时,不应获取IMHO新连接。这毫无意义。我错过什么了吗

    Java:1.8.0_91 希卡里:3.0.1 MySQL连接器:8.0.11 日食:2.5.2/2.7都试过了。 引擎:Innodb

    编辑:根据请求添加Stacktrace:

    2018年5月8日13:18:39468-[Thread-159847]-[1161705814:77]-警告-ProxyConnection.checkException(156)-HikariPool-1-连接com.mysql.jdbc。JDBC4Connection@47f8b848标记为 由于SQLSTATE(08003)、错误代码(0)而中断 com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:当autocommit=true时无法调用回滚 位于sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法) 位于sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 在sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 位于java.lang.reflect.Constructor.newInstance(Constructor.java:423) 位于com.mysql.jdbc.Util.handleNewInstance(Util.java:408) 位于com.mysql.jdbc.Util.getInstance(Util.java:383) 位于com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1023) 位于com.mysql.jdbc.SQLError.createSQLException(SQLError.java:997) 位于com.mysql.jdbc.SQLError.createSQLException(SQLError.java:983) 位于com.mysql.jdbc.SQLError.createSQLException(SQLError.java:928) 位于com.mysql.jdbc.ConnectionImpl.rollback(ConnectionImpl.java:5078) 位于com.zaxxer.hikari.pool.ProxyConnection.rollback(ProxyConnection.java:361) 位于com.zaxxer.hikari.pool.HikariProxyConnection.rollback(HikariProxyConnection.java) 位于org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicRollbackTransaction(DatabaseAccessor.java:1700) 位于org.eclipse.persistence.internal.databaseaccess.DatasourceAccessor.rollbackTransaction(DatasourceAccessor.java:688) 位于org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.rollbackTransaction(DatabaseAccessor.java:1691) 位于org.eclipse.persistence.internal.sessions.AbstractSession.basicRollbackTransaction(AbstractSession.java:779) 位于org.eclipse.persistence.sessions.server.ClientSession.basicRollbackTransaction(ClientSession.java:196) 位于org.eclipse.persistence.internal.sessions.AbstractSession.rollbackTransaction(AbstractSession.java:3795) 位于org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.rollbackTransaction(UnitOfWorkImpl.java:4670) 位于org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.rollbackTransaction(RepeatableWriteUnitOfWork.java:529) 位于org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.rollbackTransaction(RepeatableWriteUnitOfWork.java:545) 位于org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1480) 位于org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531) 位于org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.CommitroTunitOfWork(RepeatableWriteUnitOfWork.java:277) 位于org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169) 位于org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132) 在com.paytm.wallet.dao.domain.userbenginiarymanager.updateBenefeciaryDetails上(userbenginiarymanager.java:81) 在com.paytm.wallet.web.wrapper.business.impl.userbenginiaryhelper.addbenginiary(userbenginiaryhelper.java:247) 在com.paytm.wallet.web.concurrent.addbenginiarythread.run上(addbenginiarythread.java:36)
    在java.lang.Thread.run(Thread.java:745)

    incrementCallCount是通用的,用于任何调用,而不仅仅是回滚。显示初始异常中的堆栈。虽然这似乎是一个bug,但需要原始异常的上下文来查看事务为何显示为活动状态,并允许您调用回滚。添加了堆栈跟踪。请检查。可能是重复的嗯……是的。类似的问题。不过,这个答案并没有直接解决新连接回滚的问题。我们没有使用MyISAM。@Chris——你能检查一下stacktrace吗?