Uploaded image for project: 'Infinispan'
  1. Infinispan
  2. ISPN-1168

Support for interposed synchronization

This issue belongs to an archived project. You can view it, but you can't modify it. Learn more

    • Icon: Task Task
    • Resolution: Done
    • Icon: Major Major
    • 5.0.0.CR5
    • 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

            resolved by Scott and Stuart - thanks!

            Mircea Markus (Inactive) added a comment - resolved by Scott and Stuart - thanks!

            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).

            Scott Marlow added a comment - 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...

            Scott Marlow added a comment - 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...

            Scott Marlow added a comment - 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

            Galder Zamarreño added a comment - @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

            Mircea Markus (Inactive) added a comment - - edited

            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.

            Mircea Markus (Inactive) added a comment - - edited 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

            Scott Marlow added a comment - 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.

            Scott Marlow added a comment - 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?

            Manik Surtani (Inactive) added a comment - 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.

            Manik Surtani (Inactive) added a comment - @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.

            Mircea Markus (Inactive) added a comment - 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.

            Mircea Markus (Inactive) added a comment - 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.

              mircea.markus Mircea Markus (Inactive)
              smarlow1@redhat.com Scott Marlow
              Archiver:
              rhn-support-adongare Amol Dongare

                Created:
                Updated:
                Resolved:
                Archived: