1 2 Previous Next 22 Replies Latest reply on Sep 21, 2012 5:49 AM by jmesnil

    Transaction contract in HornetQ Resource Adapter is broken

    jmesnil

      I've been working on making the HornetQ RA works in AS7 standalone.

       

      The maing goal is to be able to consume messages in a MDB from a remote JMS server.

      The secondary goal is to validate that we can use the HornetQ RA in any app server (starting with AS7 standalone as the first candidate)

       

      I track this with HORNETQ-1030.

       

      First blocker was that the hornetq-ra.rar does not contain all the required jars (netty was missing)

       

      Second blocker is that HornetQ RA requires to be able to locate the app server transaction manager to support transactions.

      After reading again (and again and again!) the JCA 1.6 spec, I think this dependency is wrong. in figure 7.4 of the spect, the only thing that the RA must expose is a LocalTransaction and XAResource.

      But there is no arrow that links the RA to the transaction manager. Looking at the HornetQ ra code, we need the TM to check whether there is an active transaction, flag the tx as rollback only or set its timeout.

       

      We don't need the TM to know if there is an active tx, we can have a flag which is updated for every call to start/prepare/commit, etc.

      In the same order, I don't think it is right for a *XA resource* to flag the tx as rollback only. When we encounter such a condition, we should throw the correct XAException from prepare instead.

      And I don't see why a XA Resource has to change the tx timeout. What if another XA resource (like a JDBC connection) would do the same when it is enlisted after HornetQ RA?

       

      Currently, when the RA is deployed in JBoss AS5 or AS7, it has a hack to locate the TM using a static locator method specific to the app server. This goes agains the JCA spec which was to avoid N*M deployment cases.

       

      (there is a separate use case to be able to support auto recovery which also requires a hack to locate AS7 specific classes)

       

      I think this dependency from HornetQ RA (and *core*) to a transaction manager is incorrect. We should not require a TM (which manage the tx boundaries) to be able to implement correctly a XA resource.

      The RA's HornetQMessageHandler is instantiated with a TM to check whether the handler is in a XA transaction without a TM. I don't think we have to have that code, let's be a good XA resource citizen and let the TM handle the transaction...

       

      We want to have a HornetQ RA that can be deployed in *any* JCA-compliant app server. Require hacks for every one of this app server is not the correct solution. Let's get rid of this dependency to the TM and we will make the RA much more simpler to deploy.

       

      wdyt?

        • 1. Re: Transaction contract in HornetQ Resource Adapter is broken
          ataylor

          First blocker was that the hornetq-ra.rar does not contain all the required jars (netty was missing)

          yes, this is an issue

           

          Second blocker is that HornetQ RA requires to be able to locate the app server transaction manager to support transactions.

          After reading again (and again and again!) the JCA 1.6 spec, I think this dependency is wrong. in figure 7.4 of the spect, the only thing that the RA must expose is a LocalTransaction and XAResource.

          But there is no arrow that links the RA to the transaction manager. Looking at the HornetQ ra code, we need the TM to check whether there is an active transaction, flag the tx as rollback only or set its timeout.

          you are correct about the spec, however there are 2 areas where there is a problem

           

          1) tx timeouts, hq has a timeout and so does the tm, we need a way of being able to set this on th etm, this is the only way

           

          2) the second is that we have seen instances where the container doesnt set the tx as failed if there is an initial problem cerating it, i.e. on beforeDelivery. this was causing inconsistencies

           

          We don't need the TM to know if there is an active tx, we can have a flag which is updated for every call to start/prepare/commit, etc.

          In the same order, I don't think it is right for a *XA resource* to flag the tx as rollback only. When we encounter such a condition, we should throw the correct XAException from prepare instead.

          And I don't see why a XA Resource has to change the tx timeout. What if another XA resource (like a JDBC connection) would do the same when it is enlisted after HornetQ RA?

          we encounter it at the RA level not the core API level, how would we know.

           

          Currently, when the RA is deployed in JBoss AS5 or AS7, it has a hack to locate the TM using a static locator method specific to the app server. This goes agains the JCA spec which was to avoid N*M deployment cases.

           

          (there is a separate use case to be able to support auto recovery which also requires a hack to locate AS7 specific classes)

           

          I think this dependency from HornetQ RA (and *core*) to a transaction manager is incorrect. We should not require a TM (which manage the tx boundaries) to be able to implement correctly a XA resource.

          The RA's HornetQMessageHandler is instantiated with a TM to check whether the handler is in a XA transaction without a TM. I don't think we have to have that code, let's be a good XA resource citizen and let the TM handle the transaction...

          the point is it doesnt handle it so we have to

          We want to have a HornetQ RA that can be deployed in *any* JCA-compliant app server. Require hacks for every one of this app server is not the correct solution. Let's get rid of this dependency to the TM and we will make the RA much more simpler to deploy.

           

          wdyt?

          It will work with any jca complian app servers, we dont need the tm for certain cases, if beforeDelivery throws an exception but has still ceated a TX and the consumption of the message is part of this we need to st the tx as rollbackonly so when we call afterDelivery the tm rolls it back

          • 2. Re: Transaction contract in HornetQ Resource Adapter is broken
            leosbitto

            Andy Taylor wrote:

             

            tx timeouts, hq has a timeout and so does the tm, we need a way of being able to set this on th etm, this is the only way

             

             

            I think that the proper way is to configure the timeouts only for TransactionManager, which should propagate it by calling this method: http://docs.oracle.com/javase/6/docs/api/javax/transaction/xa/XAResource.html#setTransactionTimeout(int)

            • 3. Re: Transaction contract in HornetQ Resource Adapter is broken
              ataylor

              yes, but how would you propogate it from the activation spec to the transaction manager?

               

              ie.

               

              activationConfig = { @ActivationConfigProperty(propertyName = "transactionTimeout", propertyValue = "5000")  }

               

              on the MDB

              • 4. Re: Transaction contract in HornetQ Resource Adapter is broken
                leosbitto

                Andy Taylor wrote:

                 

                yes, but how would you propogate it from the activation spec to the transaction manager?

                 

                ie.

                 

                activationConfig = { @ActivationConfigProperty(propertyName = "transactionTimeout", propertyValue = "5000")  }

                 

                on the MDB

                 

                Well, I have always hated hardcoding such values, therefore I have never used these annotations. They are JBoss proprietary, aren't they? The JEE standard way seems to be to use BMT and this method: http://docs.oracle.com/javaee/6/api/javax/transaction/UserTransaction.html#setTransactionTimeout(int)

                • 5. Re: Transaction contract in HornetQ Resource Adapter is broken
                  jaikiran

                  Leos Bitto wrote:

                   

                  Andy Taylor wrote:

                   

                  yes, but how would you propogate it from the activation spec to the transaction manager?

                   

                  ie.

                   

                  activationConfig = { @ActivationConfigProperty(propertyName = "transactionTimeout", propertyValue = "5000")  }

                   

                  on the MDB

                   

                  Well, I have always hated hardcoding such values, therefore I have never used these annotations. They are JBoss proprietary, aren't they?

                  No they aren't. They are EE specified annotations and can also be configured via ejb-jar.xml for the MDB.

                  • 6. Re: Transaction contract in HornetQ Resource Adapter is broken
                    leosbitto

                    jaikiran pai wrote:

                     

                    Leos Bitto wrote:

                     

                    Andy Taylor wrote:

                     

                    yes, but how would you propogate it from the activation spec to the transaction manager?

                     

                    ie.

                     

                    activationConfig = { @ActivationConfigProperty(propertyName = "transactionTimeout", propertyValue = "5000")  }

                     

                    on the MDB

                     

                    Well, I have always hated hardcoding such values, therefore I have never used these annotations. They are JBoss proprietary, aren't they?

                    No they aren't. They are EE specified annotations and can also be configured via ejb-jar.xml for the MDB.

                    My bad then. Could you please point me to the JEE specification where it describes the meaning of propertyName = "transactionTimeout"?

                    • 7. Re: Transaction contract in HornetQ Resource Adapter is broken
                      ataylor

                      Well, I have always hated hardcoding such values, therefore I have never used these annotations. They are JBoss proprietary, aren't they?

                      Whether properties like this are propriety or not is moot, they are there and have been for a long time, developers want and use thrm and we have to therefore support them.

                      • 8. Re: Transaction contract in HornetQ Resource Adapter is broken
                        leosbitto

                        Andy Taylor wrote:

                         

                        Whether properties like this are propriety or not is moot, they are there and have been for a long time, developers want and use thrm and we have to therefore support them.

                         

                        Of course that you have to keep backward compatibility. My notice about transactionTimeout being JBoss proprietary was meant to provide a hint for making the resource adapter portable: use the JBoss way of locating TransactionManager manager only if you detect that your client uses the JBoss way of specifying the MDB transaction timeout.

                        • 9. Re: Transaction contract in HornetQ Resource Adapter is broken
                          jaikiran

                          Leos Bitto wrote:

                           

                          jaikiran pai wrote:

                           

                          Leos Bitto wrote:

                           

                          Andy Taylor wrote:

                           

                          yes, but how would you propogate it from the activation spec to the transaction manager?

                           

                          ie.

                           

                          activationConfig = { @ActivationConfigProperty(propertyName = "transactionTimeout", propertyValue = "5000")  }

                           

                          on the MDB

                           

                          Well, I have always hated hardcoding such values, therefore I have never used these annotations. They are JBoss proprietary, aren't they?

                          No they aren't. They are EE specified annotations and can also be configured via ejb-jar.xml for the MDB.

                          My bad then. Could you please point me to the JEE specification where it describes the meaning of propertyName = "transactionTimeout"?

                          I was actually talking about the @ActivationConfigProperty annotation since I thought that's what you meant by JBoss proprietary. The property names however can be vendor specific.

                          • 10. Re: Transaction contract in HornetQ Resource Adapter is broken
                            ataylor

                            Of course that you have to keep backward compatibility. My notice about transactionTimeout being JBoss proprietary was meant to provide a hint for making the resource adapter portable: use the JBoss way of locating TransactionManager manager only if you detect that your client uses the JBoss way of specifying the MDB transaction timeout.

                            The transactionTimeout is proprietary to the HornetQ Adapter not jboss so it will work with any App server. Using the JBoss way of locating the TM  is what we do.

                            • 11. Re: Transaction contract in HornetQ Resource Adapter is broken
                              leosbitto

                              Andy Taylor wrote:

                               

                              Of course that you have to keep backward compatibility. My notice about transactionTimeout being JBoss proprietary was meant to provide a hint for making the resource adapter portable: use the JBoss way of locating TransactionManager manager only if you detect that your client uses the JBoss way of specifying the MDB transaction timeout.

                              The transactionTimeout is proprietary to the HornetQ Adapter not jboss so it will work with any App server. Using the JBoss way of locating the TM  is what we do.

                               

                              Then I guess it is easy to document that transactionTimeout works only in JBoss AS, and make sure that the JBoss specific way of locating TransactionManager is really attempted only if transactionTimeout is used by the client code.

                              • 12. Re: Transaction contract in HornetQ Resource Adapter is broken
                                ataylor

                                Then I guess it is easy to document that transactionTimeout works only in JBoss AS, and make sure that the JBoss specific way of locating TransactionManager is really attempted only if transactionTimeout is used by the client code.

                                actually it will work in any app server if you implement a TransactionManagerLocator class

                                • 13. Re: Transaction contract in HornetQ Resource Adapter is broken
                                  leosbitto

                                  Andy Taylor wrote:

                                   

                                  Then I guess it is easy to document that transactionTimeout works only in JBoss AS, and make sure that the JBoss specific way of locating TransactionManager is really attempted only if transactionTimeout is used by the client code.

                                  actually it will work in any app server if you implement a TransactionManagerLocator class

                                  That's cool! However, how am I supposed to provide my implementation of TransactionManagerLocator to the HornetQ resource adapter? If I understand it correctly, your default implementation is the only place where the dependency on the JBoss way of locating TransactionManager is, correct?

                                  • 14. Re: Transaction contract in HornetQ Resource Adapter is broken
                                    ataylor

                                    That's cool! However, how am I supposed to provide my implementation of TransactionManagerLocator to the HornetQ resource adapter? If I understand it correctly, your default implementation is the only place where the dependency on the JBoss way of locating TransactionManager is, correct?

                                    you implement a class with a method that returns a TM and set transactionManagerLocatorClass and transactionManagerLocatorMethod properties on the resource adapter

                                    1 2 Previous Next