Should it be TMSUSPEND instead of TMSUCCESS in XAResourceManager at line 151?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Should it be TMSUSPEND instead of TMSUCCESS in XAResourceManager at line 151?

Vlasov, Pavel
Hello,

I'm playing with running the same transaction in several parallel threads. My code is based on JtaTest.testTransactionContextCleanup test (see below). I noticed that when I do btm.suspend() in the thread run() method then resources' end() method is invoked with TMSUCCESS flag. Also end is not invoked in the main thread before commit. I found that in XAResourceManager line 151 TMSUCCESS flag is passed to the xaResourceHolderState.end() method. I'm not an expert in JTA, but I'd expect that XASUSPEND shall be passed here and also that XAResource.end() shall be invoked before commit with TMSUCCESS flag. Please advise whether passing TMSUCCESS from suspend is a bug or by design.
---
Thank you, Pavel.


Code:

        assertEquals(Status.STATUS_NO_TRANSACTION, btm.getStatus());

        btm.begin();
        assertEquals(Status.STATUS_ACTIVE, btm.getStatus());
       
        XAResource res = new LoggingXAResource(new MockXAResource(new MockitoXADataSource()), "Outer");
       
        EhCacheXAResourceProducer.registerXAResource("outer", res);
       
        final Transaction tx = btm.getTransaction();
       
        tx.enlistResource(res);

        // commit on a different thread
        Thread t = new Thread() {
            public void run() {
                try {
                btm.resume(tx);
                    XAResource res = new LoggingXAResource(new MockXAResource(new MockitoXADataSource()), "Inner");
                   
                    EhCacheXAResourceProducer.registerXAResource("inner", res);
                   
                    btm.getTransaction().enlistResource(res);
               
                btm.suspend();
//                    tx.commit();
                } catch (Exception ex) {
                    ex.printStackTrace();
                    fail();
                }
            }
        };

        t.start();
        t.join();

        btm.rollback();
        assertNull(btm.getTransaction());

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Should it be TMSUSPEND instead of TMSUCCESS in XAResourceManager at line 151?

Vlasov, Pavel
In addition to my previous post - I changed TMSUCCESS to TMSUSPEND and after that the transaction manager invokes end(TMSUSPEND) in the thread and end(TMSUCCESS) in the main thread, which seems reasonable. One more question - shall the transaction manager invoke start(TMRESUME) of the outer (already enlisted) resource from btm.resume() call?

-----Original Message-----
From: Vlasov, Pavel [GCG-NAOT]
Sent: Monday, February 13, 2012 1:56 PM
To: [hidden email]
Subject: [btm-user] Should it be TMSUSPEND instead of TMSUCCESS in XAResourceManager at line 151?

Hello,

I'm playing with running the same transaction in several parallel threads. My code is based on JtaTest.testTransactionContextCleanup test (see below). I noticed that when I do btm.suspend() in the thread run() method then resources' end() method is invoked with TMSUCCESS flag. Also end is not invoked in the main thread before commit. I found that in XAResourceManager line 151 TMSUCCESS flag is passed to the xaResourceHolderState.end() method. I'm not an expert in JTA, but I'd expect that XASUSPEND shall be passed here and also that XAResource.end() shall be invoked before commit with TMSUCCESS flag. Please advise whether passing TMSUCCESS from suspend is a bug or by design.
---
Thank you, Pavel.


Code:

        assertEquals(Status.STATUS_NO_TRANSACTION, btm.getStatus());

        btm.begin();
        assertEquals(Status.STATUS_ACTIVE, btm.getStatus());
       
        XAResource res = new LoggingXAResource(new MockXAResource(new MockitoXADataSource()), "Outer");
       
        EhCacheXAResourceProducer.registerXAResource("outer", res);
       
        final Transaction tx = btm.getTransaction();
       
        tx.enlistResource(res);

        // commit on a different thread
        Thread t = new Thread() {
            public void run() {
                try {
                btm.resume(tx);
                    XAResource res = new LoggingXAResource(new MockXAResource(new MockitoXADataSource()), "Inner");
                   
                    EhCacheXAResourceProducer.registerXAResource("inner", res);
                   
                    btm.getTransaction().enlistResource(res);
               
                btm.suspend();
//                    tx.commit();
                } catch (Exception ex) {
                    ex.printStackTrace();
                    fail();
                }
            }
        };

        t.start();
        t.join();

        btm.rollback();
        assertNull(btm.getTransaction());

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RE: Should it be TMSUSPEND instead of TMSUCCESS in XAResourceManager at line 151?

Ludovic Orban-2
Calling TransactionManager.suspend() doesn't necessarily means calling XAResource.end(TMSUSPEND).

The BTM suspend implementation was written with databases and JMS servers limitations in mind. While that may look strange at first, the end result is the same and this way of doing transaction suspension is better supported by XA resources.

Have a look at this conversation if you're interested in the details: http://archives.postgresql.org/pgsql-jdbc/2006-10/msg00059.php

And yes, if you call XAResource.end(TMSUSPEND) on TransactionManager.suspend() you have to call XAResource.start(TMRESUME) on TransactionManager.resume().


2012/2/13 Vlasov, Pavel <[hidden email]>
In addition to my previous post - I changed TMSUCCESS to TMSUSPEND and after that the transaction manager invokes end(TMSUSPEND) in the thread and end(TMSUCCESS) in the main thread, which seems reasonable. One more question - shall the transaction manager invoke start(TMRESUME) of the outer (already enlisted) resource from btm.resume() call?

-----Original Message-----
From: Vlasov, Pavel [GCG-NAOT]
Sent: Monday, February 13, 2012 1:56 PM
To: [hidden email]
Subject: [btm-user] Should it be TMSUSPEND instead of TMSUCCESS in XAResourceManager at line 151?

Hello,

I'm playing with running the same transaction in several parallel threads. My code is based on JtaTest.testTransactionContextCleanup test (see below). I noticed that when I do btm.suspend() in the thread run() method then resources' end() method is invoked with TMSUCCESS flag. Also end is not invoked in the main thread before commit. I found that in XAResourceManager line 151 TMSUCCESS flag is passed to the xaResourceHolderState.end() method. I'm not an expert in JTA, but I'd expect that XASUSPEND shall be passed here and also that XAResource.end() shall be invoked before commit with TMSUCCESS flag. Please advise whether passing TMSUCCESS from suspend is a bug or by design.
---
Thank you, Pavel.


Code:

       assertEquals(Status.STATUS_NO_TRANSACTION, btm.getStatus());

       btm.begin();
       assertEquals(Status.STATUS_ACTIVE, btm.getStatus());

       XAResource res = new LoggingXAResource(new MockXAResource(new MockitoXADataSource()), "Outer");

       EhCacheXAResourceProducer.registerXAResource("outer", res);

       final Transaction tx = btm.getTransaction();

       tx.enlistResource(res);

       // commit on a different thread
       Thread t = new Thread() {
           public void run() {
               try {
                       btm.resume(tx);
                   XAResource res = new LoggingXAResource(new MockXAResource(new MockitoXADataSource()), "Inner");

                   EhCacheXAResourceProducer.registerXAResource("inner", res);

                   btm.getTransaction().enlistResource(res);

                       btm.suspend();
//                    tx.commit();
               } catch (Exception ex) {
                   ex.printStackTrace();
                   fail();
               }
           }
       };

       t.start();
       t.join();

       btm.rollback();
       assertNull(btm.getTransaction());

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email



Loading...