[hibernate-commits] Hibernate SVN: r19972 - search/branches/Branch_3_2/hibernate-search/src/main/java/org/hibernate/search/backend/impl.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Jul 20 05:14:26 EDT 2010


Author: epbernard
Date: 2010-07-20 05:14:26 -0400 (Tue, 20 Jul 2010)
New Revision: 19972

Modified:
   search/branches/Branch_3_2/hibernate-search/src/main/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java
   search/branches/Branch_3_2/hibernate-search/src/main/java/org/hibernate/search/backend/impl/PostTransactionWorkQueueSynchronization.java
Log:
HSEARCH-540 register both JTA Synchronization and action's registerProcess

This circumvent a bug in Core see email on the mailing list hibernate-dev
"Re: [hibernate-dev] Exceptions thrown in a tx synchronization are eaten"
The before tx completion process is called before tx synchronizations, and in JTA the auto-flush at the end of a session is done using a TX synchronization

Modified: search/branches/Branch_3_2/hibernate-search/src/main/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java
===================================================================
--- search/branches/Branch_3_2/hibernate-search/src/main/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java	2010-07-20 09:05:09 UTC (rev 19971)
+++ search/branches/Branch_3_2/hibernate-search/src/main/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java	2010-07-20 09:14:26 UTC (rev 19972)
@@ -82,10 +82,25 @@
 		if ( isRealTransactionInProgress() ) {
 			//use {Before|After}TransactionCompletionProcess instead of registerTransaction because it does not
 			//swallow transactions.
+			/*
+             * HSEARCH-540: the pre process must be both a BeforeTransactionCompletionProcess and a TX Synchronization.
+             *
+             * In a resource-local tx env, the beforeCommit phase is called after the flush, and prepares work queue.
+             * Also, any exceptions that occur during that are propagated (if a Synchronization was used, the exceptions
+             * would be eaten).
+             *
+             * In a JTA env, the before transaction completion is called before the flush, so not all changes are yet
+             * written. However, Synchronization-s do propagate exceptions, so they can be safely used.
+             */
+
 			final ActionQueue actionQueue = eventSource.getActionQueue();
 			actionQueue.registerProcess( new DelegateToSynchronizationOnBeforeTx( synchronization ) );
+			eventSource.getTransaction().registerSynchronization(
+					new BeforeCommitSynchronizationDelegator( synchronization )
+			);
+
+			//executed in all environments
 			actionQueue.registerProcess( new DelegateToSynchronizationOnAfterTx( synchronization ) );
-//			eventSource.getTransaction().registerSynchronization( synchronization );
 		}
 		else {
 			//registerSynchronization is only called if isRealTransactionInProgress or if
@@ -165,5 +180,21 @@
 			}
 		}
 	}
+
+	private static class BeforeCommitSynchronizationDelegator implements Synchronization {
+		private final Synchronization synchronization;
+
+		public BeforeCommitSynchronizationDelegator(Synchronization sync) {
+			this.synchronization = sync;
+		}
+
+		public void beforeCompletion() {
+			this.synchronization.beforeCompletion();
+		}
+
+		public void afterCompletion(int status) {
+			//do not delegate
+		}
+	}
 	
 }

Modified: search/branches/Branch_3_2/hibernate-search/src/main/java/org/hibernate/search/backend/impl/PostTransactionWorkQueueSynchronization.java
===================================================================
--- search/branches/Branch_3_2/hibernate-search/src/main/java/org/hibernate/search/backend/impl/PostTransactionWorkQueueSynchronization.java	2010-07-20 09:05:09 UTC (rev 19971)
+++ search/branches/Branch_3_2/hibernate-search/src/main/java/org/hibernate/search/backend/impl/PostTransactionWorkQueueSynchronization.java	2010-07-20 09:14:26 UTC (rev 19972)
@@ -27,9 +27,12 @@
 import javax.transaction.Status;
 import javax.transaction.Synchronization;
 
+import org.slf4j.Logger;
+
 import org.hibernate.search.backend.QueueingProcessor;
 import org.hibernate.search.backend.Work;
 import org.hibernate.search.backend.WorkQueue;
+import org.hibernate.search.util.LoggerFactory;
 import org.hibernate.search.util.WeakIdentityHashMap;
 
 /**
@@ -38,6 +41,8 @@
  * @author Emmanuel Bernard
  */
 public class PostTransactionWorkQueueSynchronization implements Synchronization {
+
+	private static final Logger log = LoggerFactory.make();
 	
 	/**
 	 * FullTextIndexEventListener is using a WeakIdentityHashMap<Session,Synchronization>
@@ -47,6 +52,7 @@
 	
 	private final QueueingProcessor queueingProcessor;
 	private boolean consumed;
+	private boolean prepared;
 	private final WeakIdentityHashMap queuePerTransaction;
 	private WorkQueue queue = new WorkQueue();
 
@@ -67,7 +73,13 @@
 	}
 
 	public void beforeCompletion() {
-		queueingProcessor.prepareWorks(queue);
+		if ( prepared ) {
+			log.trace("This transaction has already been processed, ignoring beforeCompletion()");
+		}
+		else {
+			queueingProcessor.prepareWorks(queue);
+			prepared = true;
+		}
 	}
 
 	public void afterCompletion(int i) {



More information about the hibernate-commits mailing list