Temporary fix until the SPIs can be reworked. Remove the transaction observer on Session close and added some checks to ensure the session is still open when the listeners fire.
This commit is contained in:
parent
779e70df4d
commit
287c0eba88
|
@ -284,6 +284,11 @@ public class TransactionCoordinatorImpl implements TransactionCoordinator {
|
|||
observers.add( observer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeObserver(TransactionObserver observer) {
|
||||
observers.remove( observer );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public boolean isTransactionJoinable() {
|
||||
|
@ -329,7 +334,7 @@ public class TransactionCoordinatorImpl implements TransactionCoordinator {
|
|||
@Override
|
||||
public void sendAfterTransactionCompletionNotifications(TransactionImplementor hibernateTransaction, int status) {
|
||||
final boolean successful = JtaStatusHelper.isCommitted( status );
|
||||
for ( TransactionObserver observer : observers ) {
|
||||
for ( TransactionObserver observer : new ArrayList<TransactionObserver>( observers ) ) {
|
||||
observer.afterCompletion( successful, hibernateTransaction );
|
||||
}
|
||||
synchronizationRegistry.notifySynchronizationsAfterTransactionCompletion( status );
|
||||
|
|
|
@ -73,6 +73,13 @@ public interface TransactionCoordinator extends Serializable {
|
|||
*/
|
||||
public void addObserver(TransactionObserver observer);
|
||||
|
||||
/**
|
||||
* Removed an observer from the coordinator.
|
||||
*
|
||||
* @param observer The observer to remove.
|
||||
*/
|
||||
public void removeObserver(TransactionObserver observer);
|
||||
|
||||
/**
|
||||
* Can we join to the underlying transaction?
|
||||
*
|
||||
|
|
|
@ -200,6 +200,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
private transient LoadQueryInfluencers loadQueryInfluencers;
|
||||
|
||||
private final transient boolean isTransactionCoordinatorShared;
|
||||
private transient TransactionObserver transactionObserver;
|
||||
|
||||
/**
|
||||
* Constructor used for openSession(...) processing, as well as construction
|
||||
|
@ -270,27 +271,42 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
|
||||
// add a transaction observer so that we can handle delegating managed actions back to THIS session
|
||||
// versus the session that created (and therefore "owns") the transaction coordinator
|
||||
transactionCoordinator.addObserver(
|
||||
new TransactionObserver() {
|
||||
transactionObserver = new TransactionObserver() {
|
||||
@Override
|
||||
public void afterBegin(TransactionImplementor transaction) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeCompletion(TransactionImplementor transaction) {
|
||||
if ( SessionImpl.this.flushBeforeCompletionEnabled ) {
|
||||
if ( isOpen() ) {
|
||||
if ( flushBeforeCompletionEnabled ){
|
||||
SessionImpl.this.managedFlush();
|
||||
}
|
||||
getActionQueue().beforeTransactionCompletion();
|
||||
}
|
||||
else {
|
||||
if (actionQueue.hasAfterTransactionActions()){
|
||||
LOG.log( Logger.Level.DEBUG, "Session had after transaction actions that were not processed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(boolean successful, TransactionImplementor transaction) {
|
||||
if ( SessionImpl.this.autoCloseSessionEnabled ) {
|
||||
SessionImpl.this.managedClose();
|
||||
if ( isOpen() ) {
|
||||
getActionQueue().afterTransactionCompletion( successful );
|
||||
if ( autoCloseSessionEnabled ) {
|
||||
managedClose();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (actionQueue.hasAfterTransactionActions()){
|
||||
LOG.log( Logger.Level.DEBUG, "Session had after transaction actions that were not processed");
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
transactionCoordinator.addObserver( transactionObserver );
|
||||
}
|
||||
|
||||
loadQueryInfluencers = new LoadQueryInfluencers( factory );
|
||||
|
@ -335,7 +351,11 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
return transactionCoordinator.close();
|
||||
}
|
||||
else {
|
||||
return null; // ???
|
||||
if ( !getActionQueue().hasAfterTransactionActions() ){
|
||||
//remove the session as a transaction observer if it has no after transaction completion actions
|
||||
transactionCoordinator.removeObserver( transactionObserver );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
|
|
@ -191,7 +191,6 @@ public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase
|
|||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-7239" )
|
||||
@FailureExpected(jiraKey = "HHH-7239" )
|
||||
public void testSessionRemovedFromObserversOnClose() throws Exception {
|
||||
Session session = sessionFactory().openSession();
|
||||
session.getTransaction().begin();
|
||||
|
@ -235,7 +234,6 @@ public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase
|
|||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-7239" )
|
||||
@FailureExpected(jiraKey = "HHH-7239" )
|
||||
public void testChildSessionCallsAfterTransactionAction() throws Exception {
|
||||
Session session = openSession();
|
||||
|
||||
|
@ -276,7 +274,6 @@ public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase
|
|||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-7239" )
|
||||
@FailureExpected(jiraKey = "HHH-7239" )
|
||||
public void testChildSessionTwoTransactions() throws Exception {
|
||||
Session session = openSession();
|
||||
|
||||
|
|
Loading…
Reference in New Issue