But how can we write a standard test case for this issue , the bug happens if we have network issue or packet loss only at a specific time/line but once it happens a complete thread , its session , associated connection and transaction is in a stale state which can't be recovered from.
JdbcTransaction.java
1. protected void doBegin() { 2. try { 3. if ( managedConnection != null ) 4. { throw new TransactionException( "Already have an associated managed connection" ); }
5. managedConnection = transactionCoordinator().getJdbcCoordinator().getLogicalConnection().getConnection(); 6. wasInitiallyAutoCommit = managedConnection.getAutoCommit(); 7. LOG.debugv( "initial autocommit status: 8. {0}
9. ", wasInitiallyAutoCommit ); 10. if ( wasInitiallyAutoCommit ) 11. { LOG.debug( "disabling autocommit" ); managedConnection.setAutoCommit( false ); }
12. } 13. catch( SQLException e ) 14. { throw new TransactionException( "JDBC begin transaction failed: ", e ); // here we need to set managedConnection=null }
15. isDriver = transactionCoordinator().takeOwnership(); 16 .}
before this method is triggered from session.beginTransaction() -> SessionImpl -> AbstractTransactionImpl.begin() ->JdbcTransaction.doBegin()
the tranasction is in NOT_ACTIVE state with no managedConnection value
but in case line #5 is successful , we have a connection set to managedConnection and then we have issue at line #11 (managedConnection.setAutoCommit( false )) the we get the exception thrown but the managedConnection is already to some value and is not null So next time we we call beginTransaction , because this is session per thread , getCurrentSession will give the same session and use the same transaction where we will get an error at line #4 as teh condition managedConnection != null is true.
|