14 Replies Latest reply on Dec 8, 2014 11:45 AM by mmusgrov

    How to match JTS XAResourceRecord participants with a transaction

    mmusgrov

      We have a tooling request to show the participants of a JTS transaction (JBTM-2308 JTS participants are not showing up in the tooling) for a given store.

       

      My plan was to read XAResourceRecords (record type /CosTransactions/XAResourceRecord()) from the store and read the global transaction id with a view to matching it up with any ArjunaTransactionImple records in the same store. Unfortunately we do we do not encode the node name in an ArjunaTransactionImple (we only store that in the XAResourceRecords).

       

      If I knew the node name of an ArjunaTransactionImple record then I could use XATxConverter to convert the uid into an Xid and then read the gtid (using the method public static Xid getXid (Uid uid, boolean branch, int formatId)).

       

      Does anyone know if it is possible to match up XAResourceRecords with ArjunaTransactionImple records?

        • 1. Re: How to match JTS XAResourceRecord participants with a transaction
          marklittle

          It's slightly worse than you imagine. I'd have to check the code, but we only save resource state within the log of a transaction in the case that a) the optimisation is enabled (it is by default) and b) the total size of the resulting log is an atomic unit for writing to disk (e.g., a file block size). Otherwise we don't gain anything in terms of write optimisation. For typical (local) JTA transactions you're going to be ok since the number of participants is going to be small and everything should go within the log for the single write. But ...

          • 2. Re: How to match JTS XAResourceRecord participants with a transaction
            marklittle

            Could you post a summary of the discussion to date and why it wasn't relevant (I think that's the case given emails I've seen)? Thanks.

            • 3. Re: How to match JTS XAResourceRecord participants with a transaction
              marklittle

              Have you considered scanning the object store for XAResourceRecord states and activating them to pick apart the information they maintain? You'd get the transaction ID from there. Obviously it doesn't help in a distributed case but you I think you already said that isn't a concern initially?

              • 4. Re: How to match JTS XAResourceRecord participants with a transaction
                marklittle

                I'll wait to see the update to why Tom's suggestion didn't work, but I would've thought also that the Uid we save for the XAResourceRecord in the tx log is the same as the same one used by the ExtendedRR to save its state to the object store, so you could tie things together that way too.

                • 5. Re: How to match JTS XAResourceRecord participants with a transaction
                  tomjenkinson

                  Hi Mike,

                   

                  From what I can see, its not possible to do what you need. I have some code below that works in many cases, but it works due to a quirk of the implementation of order() on AbstractRecord and even then, it will not work if the XAResource is also of type org.jboss.tm.FirstResource or org.jboss.tm.LastResource as the order() implementation does not return the true uid in those cases.

                   

                  import com.arjuna.ats.arjuna.common.Uid;

                  import com.arjuna.ats.arjuna.objectstore.StoreManager;

                  import com.arjuna.ats.arjuna.state.InputObjectState;

                  import com.arjuna.ats.arjuna.tools.osb.mbean.ActionBean;

                  import com.arjuna.ats.arjuna.tools.osb.mbean.LogRecordWrapper;

                  import com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBrowser;

                  import com.arjuna.ats.arjuna.tools.osb.mbean.UidWrapper;

                   

                   

                  InputObjectState buff = new InputObjectState();

                  StoreManager.getRecoveryStore().allObjUids("/CosTransactions/XAResourceRecord", buff);

                  Uid xarUid = new Uid(buff.unpackBytes());

                  assertFalse(Uid.nullUid().equals(xarUid));

                  StoreManager.getRecoveryStore().allObjUids("/StateManager/BasicAction/TwoPhaseCoordinator/ArjunaTransactionImple", buff);

                  Uid txUid = new Uid(buff.unpackBytes());

                  ObjStoreBrowser browser = new ObjStoreBrowser();

                  browser.setType("com.arjuna.ats.internal.jta.tools.osb.mbean.jts.ArjunaTransactionImpleWrapper", "com.arjuna.ats.arjuna.tools.osb.mbean.ActionBean");

                  ActionBean ab = new ActionBean(new UidWrapper(browser, null, "/StateManager/BasicAction/TwoPhaseCoordinator/ArjunaTransactionImple", null, txUid));

                  Collection<LogRecordWrapper> participants = ab.getParticipants();

                  LogRecordWrapper next = participants.iterator().next();

                  assertTrue(next.getRecord().order().equals(xarUid));

                   

                  It would be possible to expose a getter for uidOfObject in AbstractRecord of course, however the reason the Uid of the ERR is order is so that it can use that value in its own order() implementation. If we wanted to work around that we would need to have an additional RPC in ExtendedResourceRecord to call uid() for order and our new method for the true uid()

                   

                  Hope it gives some clues,

                  Tom

                  • 6. Re: How to match JTS XAResourceRecord participants with a transaction
                    marklittle

                    OK, so why not ignore the tx log and scan the store for XAResourceRecord states as I mentioned initially? There are unlikely to be many more instances of them than transaction log instances, so it shouldn't be too much of a performance impact.

                    • 7. Re: How to match JTS XAResourceRecord participants with a transaction
                      marklittle

                      BTW [JBTM-2308] JTS participants are not showing up in the tooling - JBoss Issue Tracker says "this used to work". Is that really the case because none of this object store/logging code has changed in years?

                      • 8. Re: How to match JTS XAResourceRecord participants with a transaction
                        mmusgrov

                        Mark Little wrote:

                         

                        BTW [JBTM-2308] JTS participants are not showing up in the tooling - JBoss Issue Tracker says "this used to work". Is that really the case because none of this object store/logging code has changed in years?

                        Yes but the JMX MBean instrumentation of the log records has changed. Also there are some new subtypes of ArjunaTransactionImple that aren't showing up in the tooling which JBTM-2308 will fix.

                        • 9. Re: How to match JTS XAResourceRecord participants with a transaction
                          tomjenkinson

                          Hi guys,

                           

                          Worked this with Mark asynchronously and one of his suggestions was to go back to the Xid approach in the XARR. You end up with the following code:

                           

                          // To load in state

                          InputObjectState buff = new InputObjectState();

                           

                          // For an XARR, get the uid of the transaction out of the gtrid in the Xid

                          StoreManager.getRecoveryStore().allObjUids("/CosTransactions/XAResourceRecord", buff);

                          Uid xarUid = new Uid(buff.unpackBytes());

                          assertFalse(Uid.nullUid().equals(xarUid));

                          XARecoveryResourceImple wrapper = new XARecoveryResourceImple(xarUid);

                          XidImple xid = (XidImple) wrapper.getXid();

                          Uid txOfXar = new Uid(xid.getGlobalTransactionId());

                          assertFalse(Uid.nullUid().equals(txOfXar));

                           

                          // Scan the store for ArjunaTransactionImples and match based on the uid out of the XARR

                          StoreManager.getRecoveryStore().allObjUids("/StateManager/BasicAction/TwoPhaseCoordinator/ArjunaTransactionImple",buff);

                          Uid txUid = new Uid(buff.unpackBytes());

                          assertFalse(Uid.nullUid().equals(txUid));

                          assertTrue(txOfXar.equals(txUid));

                           

                          Clearly this will work in a local only situation (same as the original suggestion). It could be possible to hack apart the _recoveryCoordinator reference for obtaining host/port IDs etc and ping that to get details on the remote parent to make this work in a distributed case.

                           

                          Hope it helps - and thanks for the pointers Mark,

                          Tom

                          • 10. Re: How to match JTS XAResourceRecord participants with a transaction
                            marklittle

                            OK but isn't that a different issue? I don't think we've ever been able to display JTS participants - the tooling just was never completed. The current JIRA infers that it used to work - jts.XAResourceRecord instances were displayed and now aren't. If that was not the case then this is a feature request/extension. If some things like the MBean instrumentation broken something else then that's a separate JIRA.

                            • 11. Re: How to match JTS XAResourceRecord participants with a transaction
                              mmusgrov

                              Mark Little wrote:

                               

                              OK but isn't that a different issue? I don't think we've ever been able to display JTS participants - the tooling just was never completed. The current JIRA infers that it used to work - jts.XAResourceRecord instances were displayed and now aren't. If that was not the case then this is a feature request/extension. If some things like the MBean instrumentation broken something else then that's a separate JIRA.

                              I tested it on the current EAP source and on 6.3.0.ER3 and the tooling was correctly showing JTS participants. Therefore I marked the jira as an enhancement and updated the title and description of JBTM-2308 to "New JTS record types are not showing up in the tooling"

                              • 12. Re: How to match JTS XAResourceRecord participants with a transaction
                                marklittle

                                It was? Wow. No need to do more here, but could you send me a screenshot of what it used to display? I'm curious because I didn't think we'd done much here for quite a while.

                                • 13. Re: How to match JTS XAResourceRecord participants with a transaction
                                  mmusgrov

                                  I think it has always worked for the standard JTS type (ArjunaTransactionImple). I was told it wasn't working but I now realise now that that was because they must have been checking it against one of the new JTS types we don't instrument yet, namely AssumedCompleteHeuristicTransaction.

                                   

                                  Here is the screenshot again (readable this time):

                                  Screenshot from 2014-12-08 16:37:41.png

                                  • 14. Re: How to match JTS XAResourceRecord participants with a transaction
                                    mmusgrov

                                    Mark Little wrote:

                                     

                                    It was? Wow. No need to do more here,

                                    We only expose the ExtendedResourceRecords in the JTS record and ignore the XAResourceRecords stored under the type /CosTransactions/XAResourceRecord I still need the code posted by Tom since the QA team need the gtid part of the Xid insrumented. I also need that code to correctly implement the "remove" operation on the participant.