-
Task
-
Resolution: Done
-
Major
-
5.0.0.CR4
-
None
-
None
Support for interposed synchronization should be configurable to avoid the following exception:
http://pastie.org/2035067
[ISPN-1168] Support for interposed synchronization
Also, AS7 doesn't bind the TransactionSynchronizationRegistry to global jndi. So a jndi lookup is not reliable enough (better to inject class instance via configuration).
Hmm, I think we would want to pass the TransactionSynchronizationRegistry class instance via a FluentConfiguration setter similar to transactionManagerLookup(TransactionManagerLookup).
This would be via FluentConfiguration transactionSynchronizationRegistryLookup(TransactionSynchronizationRegistryLookup)
I am not sure how this works with the "<namedCache name="noXa">" setting though. I'll ask on irc...
https://github.com/scottmarlow/infinispan/commit/7610bbfce16d5a697f30a6f4d935daa6ff5fbb81 has the rest of Stuart's patch
@Scott, re: your scala errors. It would appear as if you have old source code, or old compiled classes hanging around, cos org.infinispan.core.transport package no longer contains ChannelHandlerContext. We know use Netty's ChannelHandlerContext directly which is located in org.jboss.netty.channel.ChannelHandlerContext
I think the synchronisationRegistrationPolicy="fully.qualified.name.RegistrationPolicy" doesn't account for passing the TransactionSynchronizationRegistry instance in
- the TSR is passed to the "fully.qualified.name.RegistrationPolicy", as the policy implementation is up to you so it can look it up in e.g. JNDI. The approach with TransactionSynchronizationRegistryLookup does the same thing, just in a different place. Both work for me.
re:the patch it lacks the TransactionSynchronizationRegistryLookup class.
I think the synchronisationRegistrationPolicy="fully.qualified.name.RegistrationPolicy" doesn't account for passing the TransactionSynchronizationRegistry instance in, it only identifies the desire to use a configured TransactionSynchronizationRegistry. Which needs to be injected still.
I think the policy for TransactionSynchronizationRegistry, should be built in and know how to access the injected TransactionSynchronizationRegistry.
Stuart came up with this patch last night (https://github.com/scottmarlow/infinispan/commit/ff6a0050d5f3bde4b6f661937dc8847cf0e6db1c) that is a start (doesn't take the suggestions from this jira into account yet because they didn't exist yet).
If I can get past this scala related build error, I'll take a shot at what we discussed above (I wanted to mention the change from Stuart Douglas in case it helps us). The build error that I'm hitting is here http://pastie.org/2040797
The interposed synchronization behaviour is described here: http://download.oracle.com/javaee/6/api/javax/transaction/TransactionSynchronizationRegistry.html#registerInterposedSynchronization%28javax.transaction.Synchronization%29
One concern (now/future) to be aware of is, once an interposed synchronization beforeCompletion() is invoked for the current active transaction, no further calls to transaction.registerSynchronization() can succeed (their turn to run is complete, game over). This is the situation that we are currently in (look at the exception call stack again above). The workaround, is to cascade the use of an interposed synchronization (use TransactionSynchronizationRegistry.registerInterposedSynchronization instead of Transaction.registerSynchronization). I'm not sure of all of the cases where this could occur yet (maybe CacheLoaders) but wanted to raise the concern so we all understand the possible side effects and solutions.
To summarize the possible solution if this (too late registration of a tx level sync) does happen (in another layer after fixing this jira):
1. Consider getting the Transaction.registerSynchronization to occur before the transaction ends or as part of another Synchronization that was configured via Transaction.registerSynchronization.
2. Alternative is to use TransactionSynchronizationRegistry.registerInterposedSynchronization to register the synchronization in question instead.
Are we also going to ship with an impl that uses TransactionSyncRegistry? Or is this something that is going to be impl'd and shipped with JBoss AS?
@Mircea I presume this is yours? Assigning it to you. The approach works for me, BTW.
this requires an API change, but backward compatibility is not affected, so IMO this can fit in CR5.
Suggested solution:
Expose the code that performs the registration:
<namedCache name="noXa"> <transaction useSynchronization="true" synchronisationRegistrationPolicy="fully.qualified.name.RegistrationPolicy"/> </namedCache>
the synchronizationRegistrationPolicy must implement:
public interface SynchronisationRegistrationPolicy { void registerSynchronisation(Synchronization s, Transaction t); }
with default implementation:
public class SynchronisationRegistrationPolicyImpl implements SynchronisationRegistrationPolicy { @Override public void registerSynchronisation(Synchronization s, Transaction t) { try { t.registerSynchronization(s); } catch (Exception e) { throw new CacheException("Enexpected!", e); } } }
The synchronizationRegistrationPolicy is instantiated from: TransactionTable.enlist method.
resolved by Scott and Stuart - thanks!