8 Replies Latest reply on Dec 20, 2006 11:29 AM by Manik Surtani

    Ordering of Synchronizations between JBC and Hibernate

    Brian Stansberry Master

      Continuation of discussion started at http://www.jboss.com/index.html?module=bb&op=viewtopic&t=95058.

      This takes on new urgency due to the use of JBossTS in AS 4.2 (http://jira.jboss.com/jira/browse/JBAS-3892). I hadn't realized that was the plan until today. Basically, we need to come up with a solution for this in a matter of weeks. A solution most likely involves either a new JBC release or a new Hibernate release.

      I'll paste some earlier comments included in a discussion on the jbosscache-dev list:

      "Brian Stansberry" wrote:

      Anyone have any good thoughts on what to do about it? Perhaps Hibernate exposes something like JBC's OrderedSynchronizationHandler, which the JBC integration can use to insert it's synchronization at the correct point?

      "Manik Surtani" wrote:
      Not sure, cc'ing Hibernate-all. Even if there was such an ordered sync handler, we'd have to expose a mechanism to have this injected. Perhaps via the Runtime.

      "Emmanuel Bernard" wrote:

      No, not possible right now.

      This problem roots to JTA, we really should push the ability to:
      1. guaranty synchronization ordering
      2. query/alter the synchronization list
      in a standard way.

      1. is not possible today and
      javax/transaction/TransactionSynchronizationRegistry is way too limited 2. is useful when writing frameworks on top of JavaEE as a way to keep state / avoid multiple synchronization on a per transaction basis.

        • 1. Re: Ordering of Synchronizations between JBC and Hibernate
          Brian Stansberry Master

          +1 that the suggested changes to JTA are good. But, not likely to happen in time for AS 4.2, so... ;-)

          TransactionSynchronizationRegistry.put/getResource could *possibly* be used to communicate information between Hibernate and JBC. But in any case, it's a JEE 5 feature and JBC as a 2nd level cache needs to work in legacy environments.

          Synchronization ordering a la what JBC does should be possible, although ugly. Please have a look at class org.jboss.cache.interceptors.OrderedSynchronizationHandler to get a better feel for how JBC does this. Basically, any time JBC wants to add a Synchronization, it:

          1) Calls the static OSH.getInstance(Transaction) method.
          2) OSH looks up the tx in a Map<Transaction, OSH>; if an instance is found it's returned; if not one is created, put in the map and returned.
          3) JBC adds the new Synchronization either at the head or the tail.
          4) In the afterCompletion() callback, the entry for the tx is removed from the map.

          A solution to the ordering problem would be:

          1) Hibernate creates it's own version of OSH. Called here HOSH, with the JBC version now called JOSH.
          2) When Hibernate registers synchronizations, it follows the same process as above, using HOSH.
          3) TreeCache/OptimisiticTreeCache provide the integration. When a call is invoked with a transactional context, they:

          a) Call HOSH.getInstance(tx).
          b) Call JOSH.getInstance(tx).
          c) Add the JOSH at the tail of the HOSH.

          Effect of this is that all JBC synchronizations will execute after any Hibernate synchronizations that were already added to HOSH. *Assuming* the required Hibernate synchronizations are added before the first call to TreeCache/OptimisticTreeCache, this should work.

          One thing I haven't given much thought to is any possible classloader issues.

          • 2. Re: Ordering of Synchronizations between JBC and Hibernate
            Steve Ebersole Apprentice

            Already Hibernate injects a specialized TM lookup into the TreeCache when it is used as the second level cache. So another (cleaner?) solution would be to have JBC delegate registration of its Synchronization(s) to the TM lookup. Hibernate could then intercept those calls and deal with the JBC synch in an appropriate manner to ensure the proper ordering.

            I assume your ordering is simply registration order?

            • 3. Re: Ordering of Synchronizations between JBC and Hibernate
              Brian Stansberry Master

              Yes, the ordering is registration order. The OSH API allows addition of a new Synchronization at the head or the tail of the current list.

              Something like you suggest where Hibernate can directly control this certainly seems preferable to my OSH hack. There are some problems with overloading TransactionManagerLookup with this behavior though:

              1) With EJB3 in the AS, Hibernate *does not* create the JBC instance and thus doesn't inject the TM lookup. This is because the cache is a shared cache that pre-exists the EJB deployment. See o.j.ejb3.entity.TreeCacheProviderHook. Perhaps this should be changed, although that should probably be discussed on a separate thread.

              2) The JBC TransactionManagerLookup interface is part of the public API. Adding methods to it breaks API compatibility. A subinterface with the extra methods is possible, but starts to get ugly.

              3) In an IOC container like AS 5, TransactionManagerLookup is unnecessary, at least if the cache is built by the IOC container. In such a case the TM should be directly injected. JBC 2.0 supports both direct injection and the lookup. Overloading the lookup with new behavior forces the use of the lookup.

              There is some debate on http://www.jboss.com/index.html?module=bb&op=viewtopic&t=97236 as to whether JBossTS will be used in 4.2. If it won't be, that opens up the possibility of making this a JBC 2.x-only fix. There we have more freedom to alter the API to handle this cleanly.

              • 4. Re: Ordering of Synchronizations between JBC and Hibernate
                Manik Surtani Master

                My pref is for this to be a 2.x fix only - trying to get this into 1.x (and hence AS 4.2) is just unnecessarily hacky.

                • 5. Re: Ordering of Synchronizations between JBC and Hibernate
                  Brian Stansberry Master

                  For 2.0, if the approach we want to take is to allow Hibernate to pass in some object that can control the ordering of synchronization execution, I suggest we pass this in via the InvocationContext. This avoids issues with different EJB3/Hibernate deployments stepping on each other if they are using a shared cache.

                  • 6. Re: Ordering of Synchronizations between JBC and Hibernate
                    Manik Surtani Master

                    Basically you're suggesting Hibernate passes in a Synchronization Handler for the invocation, which we use instead of our own ordered sync handler? Hacky, but probably the easiest fix for 1.4.1.

                    • 7. Re: Ordering of Synchronizations between JBC and Hibernate
                      Brian Stansberry Master

                      Not for 1.4.1, unless you want to add it. The JBossTS changes Kevin Conner mentioned offline should suffice for AS 4.2.

                      It is ugly, but in the end we need something that imposes ordering of operations between Hibernate and JBC. Making JBC a resource of the transaction and leaving Hibernate as a synchronization would also do this. But is that doable for 2.0? I doubt it.

                      • 8. Re: Ordering of Synchronizations between JBC and Hibernate
                        Manik Surtani Master

                        No, making JBC an XA resource in 2.0.0 is probably quite unfeasible.