HHH-5994 - Inserts may be delayed because TransactionCoordinatorImpl.isTransactionInProgress() returns false for non-JTA transactions

This commit is contained in:
Steve Ebersole 2011-03-09 09:52:12 -06:00
parent 121c039ecd
commit 8b94ac65a1
9 changed files with 65 additions and 3 deletions

View File

@ -70,6 +70,15 @@ public interface SessionImplementor extends Serializable {
*/
public void setAutoClear(boolean enabled);
/**
* Disable automatic transaction joining. The really only has any effect for CMT transactions. The default
* Hibernate behavior is to auto join any active JTA transaction (register {@link javax.transaction.Synchronization}).
* JPA however defines an explicit join transaction operation.
*
* See javax.persistence.EntityManager#joinTransaction
*/
public void disableTransactionAutoJoin();
/**
* Does this <tt>Session</tt> have an active Hibernate transaction
* or is there a JTA transaction in progress?

View File

@ -115,6 +115,10 @@ public class TransactionCoordinatorImpl implements TransactionCoordinator {
currentHibernateTransaction.invalidate();
}
currentHibernateTransaction = transactionFactory().createTransaction( this );
if ( transactionContext.shouldAutoJoinTransaction() ) {
currentHibernateTransaction.markForJoin();
currentHibernateTransaction.join();
}
// IMPL NOTE : reset clears synchronizations (following jta spec), but not observers!
synchronizationRegistry.clearSynchronizations();

View File

@ -50,6 +50,14 @@ public interface TransactionContext extends Serializable {
*/
public ConnectionReleaseMode getConnectionReleaseMode();
/**
* Should transactions be auto joined? Generally this is only a concern for CMT transactions. The default
* should be to auto join. JPA defines an explicit operation for joining a CMT transaction.
*
* @return Should we automatically join transactions
*/
public boolean shouldAutoJoinTransaction();
/**
* Should session automatically be closed after transaction completion in this context?
*

View File

@ -180,6 +180,7 @@ public final class SessionImpl
private transient CacheMode cacheMode = CacheMode.NORMAL;
private transient EntityMode entityMode = EntityMode.POJO;
private transient boolean autoClear; //for EJB3
private transient boolean autoJoinTransactions = true;
private transient int dontFlushFromFind = 0;
private transient boolean flushBeforeCompletionEnabled;
@ -347,6 +348,11 @@ public final class SessionImpl
return connectionReleaseMode;
}
@Override
public boolean shouldAutoJoinTransaction() {
return autoJoinTransactions;
}
public boolean isAutoCloseSessionEnabled() {
return autoCloseSessionEnabled;
}
@ -369,7 +375,7 @@ public final class SessionImpl
LOG.trace("Skipping auto-flush due to session closed");
return;
}
LOG.trace("Automatically flushing session");
LOG.trace( "Automatically flushing session" );
flush();
if ( childSessionsByEntityMode != null ) {
@ -517,7 +523,7 @@ public final class SessionImpl
}
public void managedClose() {
LOG.trace("Automatically closing session");
LOG.trace( "Automatically closing session" );
close();
}
@ -556,6 +562,12 @@ public final class SessionImpl
autoClear = enabled;
}
@Override
public void disableTransactionAutoJoin() {
errorIfClosed();
autoJoinTransactions = false;
}
/**
* Check if there is a Hibernate or JTA transaction in progress and,
* if there is not, flush if necessary, make sure the connection has
@ -2096,6 +2108,7 @@ public final class SessionImpl
connectionReleaseMode = ConnectionReleaseMode.parse( ( String ) ois.readObject() );
entityMode = EntityMode.parse( ( String ) ois.readObject() );
autoClear = ois.readBoolean();
autoJoinTransactions = ois.readBoolean();
flushMode = FlushMode.parse( ( String ) ois.readObject() );
cacheMode = CacheMode.parse( ( String ) ois.readObject() );
flushBeforeCompletionEnabled = ois.readBoolean();
@ -2155,6 +2168,7 @@ public final class SessionImpl
oos.writeObject( connectionReleaseMode.toString() );
oos.writeObject( entityMode.toString() );
oos.writeBoolean( autoClear );
oos.writeBoolean( autoJoinTransactions );
oos.writeObject( flushMode.toString() );
oos.writeObject( cacheMode.toString() );
oos.writeBoolean( flushBeforeCompletionEnabled );

View File

@ -314,6 +314,11 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
return factory.getSettings().getConnectionReleaseMode();
}
@Override
public boolean shouldAutoJoinTransaction() {
return true;
}
public boolean isAutoCloseSessionEnabled() {
return factory.getSettings().isAutoCloseSessionEnabled();
}
@ -472,6 +477,11 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
throw new UnsupportedOperationException();
}
@Override
public void disableTransactionAutoJoin() {
throw new UnsupportedOperationException();
}
public void setCacheMode(CacheMode cm) {
throw new UnsupportedOperationException();
}

View File

@ -48,6 +48,11 @@ public class TransactionContextImpl implements TransactionContext {
return transactionEnvironment.getTransactionFactory().getDefaultReleaseMode();
}
@Override
public boolean shouldAutoJoinTransaction() {
return true;
}
@Override
public boolean isAutoCloseSessionEnabled() {
return false;

View File

@ -154,6 +154,10 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
}
}
public PersistenceUnitTransactionType getTransactionType() {
return transactionType;
}
protected void postInit() {
//register in Sync if needed
if ( PersistenceUnitTransactionType.JTA.equals( transactionType ) ) {

View File

@ -113,6 +113,9 @@ public class EntityManagerImpl extends AbstractEntityManagerImpl {
if ( persistenceContextType == PersistenceContextType.TRANSACTION ) {
( (SessionImplementor) session ).setAutoClear( true );
}
if ( getTransactionType() == PersistenceUnitTransactionType.JTA ) {
( (SessionImplementor) session ).disableTransactionAutoJoin();
}
}
return session;
}

View File

@ -82,7 +82,12 @@ public abstract class AbstractDelegateSessionImplementor implements SessionImple
delegate.setAutoClear(enabled);
}
public boolean isTransactionInProgress() {
@Override
public void disableTransactionAutoJoin() {
delegate.disableTransactionAutoJoin();
}
public boolean isTransactionInProgress() {
return delegate.isTransactionInProgress();
}