Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Rollback Behaviour When Commit Fails due to no connection
Rollback Behaviour When Commit Fails due to no connection [message #1787379] Thu, 24 May 2018 10:23
Mohd Amanullah is currently offline Mohd AmanullahFriend
Messages: 1
Registered: May 2018
Junior Member
Currently, we are using HikariCP to manage our connection pool.

Given the below mentioned code snippet, we are facing the following problem:

try{
txn.begin();
entityManager.persist(someEntity);
txn.commit();// Line 1
} catch(Throwable tx ){
if(txn.isActive()){
txn.rollback(); //Line 2
}
}

EntityManager tries to commit- for that it needs a connection from the HikariCP. Hikari times out, and since we didn't get any database connection, this leads to exception. Now when transaction is attempted to be rollbacked, the rollback sequence attempts to get a connection again-

1. If connection is not found, it fails.
2. If a connection is found from the Pool, it is used. By default the connection is in autocommit= true mode, so the rollback fails and the Pool marks the connection as broken, because the expected state of the connection when rollback happens is autocommit=0.

This is weird, because one would assume that rollback should happen on the same connection as the commit was attempted; if connection was not found, there should be no rollback attempted. however this is not what is happening. This is causing healthy connections to be marked as broken, and this cycle repeats in most APIs whenever there is stress on the Pool.

We are using EclipseLink version 2.5.2, but this problem is there even in the latest version. I could trace it back to this part of the rollback sequence in 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 while doing rollback new connection should not be acquired. It makes no sense. Am I missing something?

Java: 1.8.0_91 Hikari: 3.0.1 MySQL Connector: 8.0.11 Eclipselink: 2.5.2/2.7 both tried. Engine: Innodb.

Edit: Stacktrace added as requested:

08 May 2018 13:18:39,468 -[Thread-159847]-[1161705814:77]- WARN - ProxyConnection.checkException(156) - HikariPool-1 - Connection com.mysql.jdbc.JDBC4Connection@47f8b848 marked as broken because of SQLSTATE(08003), ErrorCode(0) 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:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.jdbc.Util.handleNewInstance(Util.java:408) at com.mysql.jdbc.Util.getInstance(Util.java:383) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1023) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:997) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:983) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:928) at com.mysql.jdbc.ConnectionImpl.rollback(ConnectionImpl.java:5078) at com.zaxxer.hikari.pool.ProxyConnection.rollback(ProxyConnection.java:361) at com.zaxxer.hikari.pool.HikariProxyConnection.rollback(HikariProxyConnection.java) at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicRollbackTransaction(DatabaseAccessor.java:1700) at org.eclipse.persistence.internal.databaseaccess.DatasourceAccessor.rollbackTransaction(DatasourceAccessor.java:688) at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.rollbackTransaction(DatabaseAccessor.java:1691) at org.eclipse.persistence.internal.sessions.AbstractSession.basicRollbackTransaction(AbstractSession.java:779) at org.eclipse.persistence.sessions.server.ClientSession.basicRollbackTransaction(ClientSession.java:196) at org.eclipse.persistence.internal.sessions.AbstractSession.rollbackTransaction(AbstractSession.java:3795) at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.rollbackTransaction(UnitOfWorkImpl.java:4670) at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.rollbackTransaction(RepeatableWriteUnitOfWork.java:529) at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.rollbackTransaction(RepeatableWriteUnitOfWork.java:545) at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1480) at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531) at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277) at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169) at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132) at ....


Previous Topic:Eclipselink with JTA
Next Topic:Problem while doing Multithreading and using EntityManager
Goto Forum:
  


Current Time: Thu Apr 18 05:38:09 GMT 2024

Powered by FUDForum. Page generated in 0.01923 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top