[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