8 Replies Latest reply on Feb 15, 2008 12:07 PM by kadlecp

    Transaction bridging bug?

      Hello,

      I am JBossESB user and I am intergrating WS-Transaction into that project, including transaction bridging. I have checked out txBridge from http://anonsvn.labs.jboss.com/labs/jbosstm/workspace/jhalliday/txbridge

      When I tested txBridge and my intergation, I could see that there are bad results in my database. If one participant failed, the results of other successful participant were commited into database.. which is bad. Firstly I thought that 2-phase commit does not work well, but the problem is somewhere else.....

      There is log of txBridge demo

      11:28:55,248 INFO [STDOUT] CLIENT: obtaining userTransaction...
      11:28:55,251 INFO [STDOUT] CLIENT: starting the transaction...
      11:28:55,267 INFO [STDOUT] CLIENT: transaction ID= AtomicTransactionIdentifier: urn:a000002:c0a0:47b40ed7:1c66
      11:28:55,270 INFO [STDOUT] CLIENT: calling business Web Services...
      11:28:55,403 INFO [JaxWSClientHeaderContextProcessor] getHeaders
      11:28:55,411 INFO [JaxWSClientHeaderContextProcessor] handleOutbound
      11:28:55,423 INFO [JaxWSServerHeaderContextProcessor] getHeaders
      11:28:55,429 INFO [JaxWSServerHeaderContextProcessor] handleInbound
      11:28:55,498 INFO [JaxWSServerHeaderContextProcessor] handleOutbound
      11:28:55,503 INFO [JaxWSClientHeaderContextProcessor] handleInbound
      11:28:55,507 INFO [STDOUT] CLIENT: bookingCount: 0
      11:28:55,511 INFO [JaxWSClientHeaderContextProcessor] handleOutbound
      11:28:55,517 INFO [JaxWSServerHeaderContextProcessor] handleInbound
      11:28:55,523 INFO [JaxWSServerHeaderContextProcessor] handleOutbound
      11:28:55,531 INFO [JaxWSClientHeaderContextProcessor] handleInbound
      11:28:55,535 INFO [JaxWSClientHeaderContextProcessor] handleOutbound
      11:28:55,544 INFO [JaxWSServerHeaderContextProcessor] handleInbound
      11:28:55,548 INFO [JaxWSServerHeaderContextProcessor] handleOutbound
      11:28:55,559 INFO [JaxWSClientHeaderContextProcessor] handleInbound
      11:28:55,563 INFO [STDOUT] CLIENT: bookingCount: 2
      11:28:55,565 INFO [STDOUT] CLIENT: calling commit on the transaction...
      11:28:55,571 WARN [AbstractEntityManagerImpl] Transaction not available on beforeCompletionPhase: assuming valid
      11:28:55,745 DEBUG [BridgeParticipantAT] prepare on Xid=< 131075, 28, 64, 1-a000002:c0a0:47b40ed7:1c69
       > returning Prepared
      11:28:55,755 DEBUG [BridgeParticipantAT] commit on Xid=< 131075, 28, 64, 1-a000002:c0a0:47b40ed7:1c69
       > OK
      11:28:55,771 INFO [STDOUT] done.
      


      There is a line in the log
      11:28:55,571 WARN [AbstractEntityManagerImpl] Transaction not available on beforeCompletionPhase: a
      ssuming valid


      This is logged by hibernate when prepare is received from coordinator. It means that hibernate cannot find JTA transaction on thread, so hibernate flushes all entities into database immediately. Look at the http://anonsvn.jboss.org/repos/hibernate/entitymanager/tags/v3_2_1_GA/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
      on the line 483, Synchronization object.

      I think repair is easy, when org.jboss.txbridge.BridgeParticipantAT receives prepare, it should associate thread with JTA transaction. The code might look like
      public Vote prepare() throws WrongStateException, SystemException
       {
       log.trace("prepare(Xid="+xid+")");
      
       try {
      
       TransactionImple tx = TxImporter.getImportedTransaction(xid);
       txManager.resume(tx);
      
       // XAResource.XA_OK, XAResource.XA_RDONLY or exception. if RDONLY, don't call commit
       int result = xaTerminator.prepare(xid);
       if(result == XAResource.XA_OK) {
       log.debug("prepare on Xid="+xid+" returning Prepared");
       return new Prepared();
       } else {
       log.debug("prepare on Xid="+xid+" returning ReadOnly");
       return new ReadOnly();
       }
      
       } catch(Exception e) {
       log.debug("prepare on Xid="+xid+" returning Aborted", e);
       return new Aborted();
       } finally {
      
       try {
       txManager.suspend();
       } catch (javax.transaction.SystemException e) {
      
       e.printStackTrace();
       }
       }
      
      


      With that fix, commit is done when commit is received from coordinator, and not when prepare is received.

      What do you think? Shall be methods org.jboss.txbridge.BridgeParticipantAT.commit and org.jboss.txbridge.BridgeParticipantAT fixed in similar way?

      Thanks for comments
      Pavel Kadlec