7 Replies Latest reply on Sep 16, 2009 10:52 AM by jaikiran

    HornetQ JCA Adapter question

    ataylor

      Guys,

      HornetQ has its own RA adapter for MDB's and we have a question regarding the spec and the ejb3 implementation you may be able to answer.

      This is regarding section 12.5.6 of the JCA spec.

      Originally we used Option B and used the beforeDelivery/afterDelivery methods on MessageEndpoint to control transaction demarcation etc.

      We have recently changed this however to use Option A, we did this so we could have more control over the transactions so we could add things like local tx optimization, transaction batching etc. According to the spec with option A you don't call beforeDelivery/afterDelivery, you can see this clearly in figure 12-7 that this doesn't occur.

      The problem is that because we don't call these methods the Thread Context Classloader no longer gets set, so the question is this! Is the spec slightly ambiguous here, should we always call before/afterDelivery to do this. I would have thought that if we didn't call these then the MessageEndpoint proxy would still set the TCL before calling the MDB onMessage method.

      Any input would be appreciated!

        • 1. Re: HornetQ JCA Adapter question
          jesper.pedersen

          In both options its the end-point proxy that controls the transaction -- see Figure 12-7 in JCA 1.5. The end-point could be a MDB.

          The default behavior was changed in the generic messaging resource adapter for AS - see https://jira.jboss.org/jira/browse/JBAS-7084 - as the previous implementation worked around problems in some messaging systems.

          HTH

          • 2. Re: HornetQ JCA Adapter question
            clebert.suconic

            I had a conversation about the JCA adapter today with Carlo.


            Basically Carlo agrees with Jesper.


            Here is the transcript for future reference:



            (03:33:56 PM) wolfc: clebert: delivering multiple message within a single tx is against spec, so I'm very curious how others implement this
            (03:34:52 PM) clebert: wolfc: it's probably against the spec...
            (03:34:52 PM) clebert: also.. I believe others support sub-transactions... so I guess they used that as a way to sneak in the rule on Specj
            (03:35:10 PM) clebert: wolfc: it's against the spec.. but useful...
            (03:35:22 PM) clebert: wolfc: IMO actually: it should be made as part of the spec somehow
            (03:35:32 PM) clebert: say.. you're doing this:
            (03:35:32 PM) clebert: (forget MDBs)
            (03:35:39 PM) clebert: pseudo code coming... sec:
            (03:36:07 PM) wolfc: forget MDBs means I'm off the hook :-P
            (03:36:30 PM) clebert: int i = 0;
            (03:36:30 PM) clebert: while (true)
            (03:36:30 PM) clebert: {
            (03:36:30 PM) clebert: i++
            (03:36:30 PM) clebert: msg = consumer.receive();
            (03:36:30 PM) clebert: if (i == 500) tx.commit();
            (03:36:30 PM) clebert: }
            (03:36:38 PM) clebert: if a rollback happens here.. everything would be rolled back
            (03:36:45 PM) clebert: and everything redelivered
            (03:37:11 PM) clebert: most people will do this kind of thing when not using MDBs.. but have to do single syncs when doing MDBs
            (03:39:18 PM) clebert: wolfc: I said forget MDBs just as an example...
            (03:39:19 PM) clebert: when not using MDBs users can do this kind of thing... but when on MDBs they have to use single-syncs
            (03:39:34 PM) wolfc: but we're not talking simple MessageReceivers, we're talking JCA
            (03:40:06 PM) clebert: wolfc: yes.... I know.. this should be part of the JCA spec somehow
            (03:40:19 PM) clebert: wolfc: I mean.. IMHO
            (03:42:40 PM) wolfc: clebert: the only thing I've been seeing is that such a feature gives customers headaches.
            (03:42:53 PM) wolfc: for example: https://jira.jboss.org/jira/browse/JBPAPP-2260
            (03:43:48 PM) wolfc: basically you see support case where people complain about messages being unduly redelivered
            (03:44:19 PM) clebert: wolfc: well.. that was a bug.. right?
            (03:44:19 PM) clebert: Bugs are bugs :-)
            (03:44:53 PM) clebert: wolfc: It's very common users just using MDBs on the Application Server...
            (03:44:53 PM) clebert: But the performance for MDB is horrible because of that
            (03:45:11 PM) wolfc: yeah, the bug was batching
            (03:46:11 PM) clebert: wolfc: if we use batching... we would need to use a single consumer on the MDB... and the user would have to use it carefully.
            (03:47:05 PM) wolfc: clebert: right, which is horrible for them to implement and horrible to tune
            (03:47:28 PM) clebert: wolfc: for them .. you mean.. customers?
            (03:47:34 PM) wolfc: yes
            (03:48:11 PM) clebert: wolfc: that would be the same as doing the pseudo code above... the user would have the choice of doing it through MDBs
            (03:48:35 PM) clebert: wolfc: right now if you want performance on receiving messages.. we have to say don't use MDBs
            (03:49:09 PM) wolfc: clebert: what's faster: 1 consumer doing 100 batched or 100 MDBs?
            (03:50:16 PM) clebert: wolfc: it depends on the use case....
            (03:50:16 PM) clebert: some users need strict ordering.. that means you can only have 1 consumer.
            (03:51:35 PM) wolfc: I think I see the trick: Delivering batches of messages to each MDB endpoint can improve performance particularly when used with Acknowledge mode set to Duplicates-ok auto-acknowledge.
            (03:51:44 PM) bobmcw_ left the room (quit: Remote closed the connection).
            (03:51:46 PM) clebert: wolfc: from Messaging point of view... 100 consumers would scale.. but on the Application server that would mean 100 threads.... what would end up on more resources.
            (03:51:46 PM) clebert: at the end if you need performance we just say.. don't use MDBs
            (03:52:38 PM) wolfc: clebert: that's on WAS, but it doesn't say anything about the tx
            (03:53:22 PM) clebert: wolfc: yeah... Duplicates-ok is fine.. but most users also need to control transactions...
            (03:53:22 PM) clebert: Expand that loop to:
            (03:53:22 PM) clebert: loop
            (03:53:22 PM) clebert: {
            (03:53:22 PM) clebert: msg = consumer.receve();
            (03:53:22 PM) clebert: if (counter++ == 500) xa.commit;
            (03:53:22 PM) clebert: db.inserts, updates...etc;
            (03:53:22 PM) clebert: }
            (03:53:23 PM) wolfc: clebert: still if the ack mode is dups-ok we have some leeway
            (03:53:30 PM) clebert: say.. a store is receiving a new table or something...
            (03:53:38 PM) clebert: if you commit msg by msg.. that would take forever
            (03:54:35 PM) clebert: right now.. the user can only do this by hand with a consumer.. without using MDBs
            (03:55:14 PM) clebert: well.. the user could go around.. like.. a msg saying... get the new table.. on the onMessage it starts a consumer on another queue
            (03:55:18 PM) kkhan left the room (quit: ).
            (03:56:50 PM) clebert: wolfc: that's something I know BEA and WebSphere have
            (03:58:41 PM) wolfc: clebert: where does it say that?
            (03:58:55 PM) clebert: sec
            (04:00:33 PM) clebert: wolfc: I read both docs once.. I didn't want to link to our JIRA as I didn't want to look like plagiarism
            (04:00:46 PM) clebert: wolfc: let me see if I can find it here real quick
            (04:02:28 PM) clebert: wolfc: http://74.125.155.132/search?q=cache:kp8szn4Jc6kJ:e-docs.bea.com/wls/docs103/ejb/message_beans.html+grouping+transactions+MDB+WebLogic&cd=1&hl=en&ct=clnk&gl=us
            (04:02:28 PM) clebert: It disapperared.. I could only read it from the cache
            (04:02:34 PM) clebert: look for Transaction Batching of MDBs
            (04:03:54 PM) wolfc: clebert: okay the bea doc at least explicitly states multiple msgs / tx
            (04:04:41 PM) clebert: wolfc: I don't care much about the spec on this case... all I care is I think it's a valid use case...
            (04:04:41 PM) clebert: Maybe this should be included on the spec.. that's my point
            (04:05:36 PM) wolfc: clebert: if we want this it should be part of the proxy endpoint, not part of the RA
            (04:06:06 PM) wolfc: hmm, no that's not possible
            (04:06:32 PM) clebert: wolfc: what's not possible? add it to the spec?
            (04:06:54 PM) wolfc: no, make it part of the proxy endpoint
            (04:08:01 PM) wolfc: clebert: the RA could do option B, but do multiple deliveries instead of 1
            (04:08:15 PM) clebert: wolfc: we are doing option B ATM.
            (04:08:26 PM) clebert: wolfc: we have actually an open issue with TCCL ATM
            (04:08:30 PM) wolfc: clebert: option A is 1 msg / tx
            (04:08:38 PM) clebert: wolfc: that' s why we are asking you to look at that thread
            (04:08:52 PM) bstansb_afk is now known as bstansberry
            (04:09:17 PM) bstansberry: any maven lovers know any place maven caches snapshots besides in ~/.m2/repository ?
            (04:09:24 PM) clebert: wolfc: the batch transaction will be probably fixed later.. it's a nice to have feature
            (04:10:36 PM) clebert: wolfc: but the TCCL is a current bug we have.. any help would be appreciated on that EJB3 dev forum thread
            (04:10:36 PM) clebert: Jesper said both options need to be on the proxy endpoint.. but like what you just said goes against that I think
            (04:13:51 PM) rruss left the room (quit: Read error: 110 (Connection timed out)).
            (04:15:34 PM) wolfc: clebert: there are more points where the proper tccl isn't set in ejb3, so it's not an isolated problem
            (04:15:47 PM) wolfc: clebert: and the current proxy endpoint implementation is very messy
            (04:15:59 PM) wolfc: clebert: hacked together to work with JBossMQ
            (04:17:07 PM) clebert: wolfc: we are adding a hack in our code...
            (04:17:07 PM) clebert: we created a property hackOn
            (04:17:07 PM) clebert: If (hackOn) setTCCL(endpoing.getClass().getClassLoader());
            (04:17:07 PM) clebert: Or something like that
            (04:17:11 PM) wolfc: clebert: for the moment just use option B and you're set to go
            (04:17:25 PM) rruss [n=rruss@redhat/jboss/rruss] entered the room.
            (04:17:25 PM) mode (+v rruss ) by ChanServ
            (04:17:50 PM) clebert: wolfc: option B .. but what about beforeDelivery and afterDelivery...
            (04:17:50 PM) clebert: we don't need to call that, right?
            (04:17:50 PM) clebert: we can just use the hack and set the TCCL ourselves?
            (04:18:24 PM) wolfc: clebert: don't make matters worse.
            (04:18:24 PM) wolfc: clebert: just use option B
            (04:18:34 PM) wolfc: I don't see why that should be a problem
            (04:20:19 PM) wolfc: clebert: basically option A RAs don't function and since the proxy endpoint code has been duplicated just about everywhere you'll run into more issues with other components.
            (04:21:30 PM) clebert: wolfc: Andy is the one doing it... we needed more control over transaction.. so we are using a different option...
            (04:21:42 PM) clebert: (I don't recall if A or B.. all I know is the one where you don't call beforeDelivery)
            (04:21:45 PM) wolfc: clebert: the RA can never control the tx
            (04:22:34 PM) clebert: wolfc: can you input that on the thread pls.. so Andy will get it for sure?
            (04:22:38 PM) wolfc: I should say: the RA can never control the tx directly
            (04:24:56 PM) wolfc: clebert: jesper already put that in the thread
            (04:25:20 PM) clebert: wolfc: ok.. I was just wondering if what we were discussing about batching would still apply on that...
            (04:25:55 PM) wolfc: clebert: yep it'll. In that case we'll use option B, but do multiple deliveries and tell the proxy endpoint to not complain about it.
            (04:26:21 PM) clebert: wolfc: ok
            (04:26:31 PM) clebert: wolfc: I will put this conversation on that thread if you don't mind


            • 3. Re: HornetQ JCA Adapter question
              ataylor

               

              In both options its the end-point proxy that controls the transaction -- see Figure 12-7 in JCA 1.5. The end-point could be a MDB


              Ok, regarding how we control transactions we do it no different from the AS implementation. We basically start the tx before delivery and rollback/commit depending on the outcome. The reason we removed before/afterdelivery is because we shouldn't need to call it as we are starting the tx before the delivery.

              The issue here is that the TCCL does not get set, looking at the AS code it looks like when the TraditionalXATransactionDemarcationStrategy is used, i.e. https://jira.jboss.org/jira/browse/JBAS-7084 the same problem will occur. Jesper, you should check this.

              I can change the code back to option B and call before/afterdelivery to fix this but this introduces an extra overhead but its no biggie. The question i was asking is 'is this a bug' and if so, is there a jira and is it due to be fixed.

              • 4. Re: HornetQ JCA Adapter question
                jaikiran

                 

                "ataylor" wrote:


                The issue here is that the TCCL does not get set

                The question i was asking is 'is this a bug' and if so, is there a jira and is it due to be fixed.


                If my understanding is right, this is the same issue as

                https://jira.jboss.org/jira/browse/EJBTHREE-1876

                http://www.jboss.org/index.html?module=bb&op=viewtopic&t=159011

                • 5. Re: HornetQ JCA Adapter question
                  wolfc

                   

                  "ataylor" wrote:
                  In both options its the end-point proxy that controls the transaction -- see Figure 12-7 in JCA 1.5. The end-point could be a MDB


                  Ok, regarding how we control transactions we do it no different from the AS implementation. We basically start the tx before delivery and rollback/commit depending on the outcome. The reason we removed before/afterdelivery is because we shouldn't need to call it as we are starting the tx before the delivery.

                  You should not meddle with the tx at all. :-)


                  • 6. Re: HornetQ JCA Adapter question
                    ataylor

                     

                    You should not meddle with the tx at all. :-)


                    :), like i say this is very similar to the current AS implementation. Most of it is for optimizations.

                    If my understanding is right, this is the same issue as

                    https://jira.jboss.org/jira/browse/EJBTHREE-1876

                    http://www.jboss.org/index.html?module=bb&op=viewtopic&t=159011


                    yes, it looks like it. any one know if there are plans to fix this?

                    • 7. Re: HornetQ JCA Adapter question
                      jaikiran

                       

                      "ataylor" wrote:


                      yes, it looks like it. any one know if there are plans to fix this?


                      Yes, indeed :) I was planning to fix that issue some weeks back but got busy with other things. EJB3 releases a plugin every 2nd and 4th Friday of the month, so i plan to get this into the next plugin release in a couple of weeks.