[jboss-dev-forums] [Design of JBoss Transaction Services] - Transaction bridging bug?

kadlecp do-not-reply at jboss.com
Thu Feb 14 05:56:16 EST 2008


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

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4129363#4129363

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4129363



More information about the jboss-dev-forums mailing list