Author: epbernard
Date: 2010-07-13 11:06:59 -0400 (Tue, 13 Jul 2010)
New Revision: 19943
Modified:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java
search/trunk/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/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java
===================================================================
---
search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java 2010-07-13
13:55:32 UTC (rev 19942)
+++
search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java 2010-07-13
15:06:59 UTC (rev 19943)
@@ -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/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/PostTransactionWorkQueueSynchronization.java
===================================================================
---
search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/PostTransactionWorkQueueSynchronization.java 2010-07-13
13:55:32 UTC (rev 19942)
+++
search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/PostTransactionWorkQueueSynchronization.java 2010-07-13
15:06:59 UTC (rev 19943)
@@ -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) {
Show replies by date