Hi Weston.

"[EMAIL PROTECTED]" wrote : This is a heuristic. 
  | 
  | Technically once a resource agrees in the prepare phase, the commit must 
occur. Is the offensive resource throwing an Exception in your case? This 
should force the rollback of the other participant. When you say 'does not 
respond to the commit request' what do you mean? 

The problem is that the resource seems to be no longer available. The 
TCP-Socket times out. This of course means that the commit request might have 
reached it's destination and thereby caused the commit to be executed, but from 
my experiences so far this did not happen.
Since all communication is done via HTTP and the ResourceManager itself is not 
java an Exception is not really possible. In case of a timeout the XAResource 
at the moment throws a XAException (RMERR).

If I however set up a test case and throw whatever exception in the XAResource 
the other participant is not being rolled back. Here is some sample code:


  | The Method which does the work looks like this (called remotely):
  | 
  |   /**
  |    * @throws CreateException
  |    * @ejb.interface-method
  |    * @ejb.transaction type="Required"
  |    */
  |    public void jtaTest() throws RemoteException, CreateException {
  | 
  | ctx.lookup("java:/TransactionManager");
  |        try {
  |            TransactionManager transactionManager = (TransactionManager)new 
InitialContext().lookup("java:/TransactionManager");
  |            log.info(transactionManager.getClass());
  |            transactionManager.getTransaction().enlistResource(new 
MyXAResource());
  |            AddressValue addy2 = new AddressValue();
  |            addy2.setCity("einestadt");
  |            addy2.setId(new Long(System.currentTimeMillis()));
  |            addy2.setName("ich");
  |            addy2.setStreet("am kamp 12");
  |            AddressUtil.getLocalHome().create(addy2) ;
  |            
  |        } catch (Exception e) {
  |            e.printStackTrace();
  |            ctx.setRollbackOnly();
  |        }
  |   }
  | 
  | 
  | And this is the enlisted XAResource:
  | 
  |     private static class MyXAResource implements XAResource {
  |         Xid managedXid = null;
  | 
  |         public void commit(Xid xid, boolean b) throws XAException {
  |             log.info("Nummer 1:commiting " + xid);
  |             int testFlag=0;
  |             switch (testFlag) { 
  |                 case 0:
  |             
  |                 log.info("Nummer 1:Error during commit");
  |                 throw new XAException(XAException.XA_HEURRB);
  |                 case 1:
  |             
  |                 log.info("Nummer 1:Error during commit");
  |                 throw new RuntimeException("blabla");
  |                 case 2:
  |             
  |                 log.info("Nummer 1:Error during commit");
  |                 throw new XAException(XAException.XAER_RMERR);
  |                 
  |             }
  | 
  |             log.info("Nummer 1:done commiting");
  |         }
  | 
  |         public void end(Xid xid, int i) throws XAException {
  |             log.info("Nummer 1:end transcation " + xid);
  |         }
  | 
  |         public void forget(Xid xid) throws XAException {
  |             log.info("Nummer 1:forget transcation " + xid);
  |         }
  | 
  |         public int getTransactionTimeout() throws XAException {
  |             return 5000;  //To change body of implemented methods use File 
| Settings | File Templates.
  |         }
  | 
  |         public boolean isSameRM(XAResource xaResource) throws XAException {
  |             log.info("Nummer 1:isSameRM called");
  |             return xaResource == this;
  |         }
  | 
  |         public int prepare(Xid xid) throws XAException {
  |             boolean flag = false;
  |             log.info("Nummer 1: prepare called.");
  |             if (flag) {
  |                 throw new XAException(XAException.XA_RBCOMMFAIL );
  |             }
  | 
  |             return XA_OK;  //To change body of implemented methods use File 
| Settings | File Templates.
  |         }
  | 
  |         public Xid[] recover(int i) throws XAException {
  |             log.info("Nummer 1:recover called");
  |             return new Xid[0];  //To change body of implemented methods use 
File | Settings | File Templates.
  |         }
  | 
  |         public void rollback(Xid xid) throws XAException {
  |             boolean flag = false;
  |             if (flag) {
  |                 throw new XAException(XAException.XAER_RMERR );
  |             }
  |         }
  | 
  |         public boolean setTransactionTimeout(int i) throws XAException {
  |             return false;  //To change body of implemented methods use File 
| Settings | File Templates.
  |         }
  | 
  |         public void start(Xid xid, int flags) throws XAException {
  |             if (xid == null) throw new XAException(XAException.XAER_INVAL);
  |             if (managedXid != null) {
  |              throw new XAException(XAException.XAER_INVAL);
  |             } else {
  |                 managedXid = xid;
  |             }
  |             log.info("Nummer 1:start called " + xid + " i " +flags);
  |         }
  |     }
  | 
  | 

as you can see in commit there is always an XAException being thrown.

here is some logging


  | 11:40:15,195 INFO  [CMRTestFacadeBean] Nummer 1:Error during commit
  | 11:40:15,196 WARN  [TransactionImpl] XAException: 
tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=toaster/15, BranchQual=, 
localId=15] errorCode=XA_HEURRB
  | javax.transaction.xa.XAException
  | at 
eval.cmr.CMRTestFacadeBean$MyXAResource.commit(CMRTestFacadeBean.java:313)action.xa.XAException
  | at org.jboss.tm.TransactionImpl$Resource.commit(TransactionImpl.java:2253)
  |         at 
org.jboss.tm.TransactionImpl.commitResources(TransactionImpl.java:1784)
  |         at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:358)
  | ...
  | "[EMAIL PROTECTED]" wrote : This is a heuristic. 
  |   | 
  |   | Technically once a resource agrees in the prepare phase, the commit 
must occur. Is the offensive resource throwing an Exception in your case? This 
should force the rollback of the other participant. When you say 'does not 
respond to the commit request' what do you mean? 
  | 
  | The problem is that the resource seems to be no longer available. The 
TCP-Socket times out. This of course means that the commit request might have 
reached it's destination and thereby caused the commit to be executed, but from 
my experiences so far this did not happen.
  | Since all communication is done via HTTP and the ResourceManager itself is 
not java an Exception is not really possible.
  | 
  | If I however set up a test case and throw whatever exception in the 
XAResource the other participant is not being rolled back. Here is some sample 
code:
  | 
  | 
  |   | The Method which does the work looks like this (called remotely):
  |   | 
  |   |   /**
  |   |    * @throws CreateException
  |   |    * @ejb.interface-method
  |   |    * @ejb.transaction type="Required"
  |   |    */
  |   |    public void jtaTest() throws RemoteException, CreateException {
  |   | 
  |   | ctx.lookup("java:/TransactionManager");
  |   |        try {
  |   |            TransactionManager transactionManager = 
(TransactionManager)new InitialContext().lookup("java:/TransactionManager");
  |   |            log.info(transactionManager.getClass());
  |   |            transactionManager.getTransaction().enlistResource(new 
MyXAResource());
  |   |            AddressValue addy2 = new AddressValue();
  |   |            addy2.setCity("einestadt");
  |   |            addy2.setId(new Long(System.currentTimeMillis()));
  |   |            addy2.setName("ich");
  |   |            addy2.setStreet("am kamp 12");
  |   |         // save the address to the DB           
  |   |            AddressUtil.getLocalHome().create(addy2) ;
  |   |            
  |   |        } catch (Exception e) {
  |   |            e.printStackTrace();
  |   |            ctx.setRollbackOnly();
  |   |        }
  |   |   }
  |   | 
  |   | 
  |   | And this is the enlisted XAResource:
  |   | 
  |   |     private static class MyXAResource implements XAResource {
  |   |         Xid managedXid = null;
  |   | 
  |   |         public void commit(Xid xid, boolean b) throws XAException {
  |   |             log.info("Nummer 1:commiting " + xid);
  |   |             int testFlag=0;
  |   |             switch (testFlag) { 
  |   |                 case 0:
  |   |             
  |   |                 log.info("Nummer 1:Error during commit");
  |   |                 throw new XAException(XAException.XA_HEURRB);
  |   |                 case 1:
  |   |             
  |   |                 log.info("Nummer 1:Error during commit");
  |   |                 throw new RuntimeException("blabla");
  |   |                 case 2:
  |   |             
  |   |                 log.info("Nummer 1:Error during commit");
  |   |                 throw new XAException(XAException.XAER_RMERR);
  |   |                 
  |   |             }
  |   | 
  |   |             log.info("Nummer 1:done commiting");
  |   |         }
  |   | 
  |   |         public void end(Xid xid, int i) throws XAException {
  |   |             log.info("Nummer 1:end transcation " + xid);
  |   |         }
  |   | 
  |   |         public void forget(Xid xid) throws XAException {
  |   |             log.info("Nummer 1:forget transcation " + xid);
  |   |         }
  |   | 
  |   |         public int getTransactionTimeout() throws XAException {
  |   |             return 5000;  //To change body of implemented methods use 
File | Settings | File Templates.
  |   |         }
  |   | 
  |   |         public boolean isSameRM(XAResource xaResource) throws 
XAException {
  |   |             log.info("Nummer 1:isSameRM called");
  |   |             return xaResource == this;
  |   |         }
  |   | 
  |   |         public int prepare(Xid xid) throws XAException {
  |   |             boolean flag = false;
  |   |             log.info("Nummer 1: prepare called.");
  |   |             if (flag) {
  |   |                 throw new XAException(XAException.XA_RBCOMMFAIL );
  |   |             }
  |   | 
  |   |             return XA_OK;  //To change body of implemented methods use 
File | Settings | File Templates.
  |   |         }
  |   | 
  |   |         public Xid[] recover(int i) throws XAException {
  |   |             log.info("Nummer 1:recover called");
  |   |             return new Xid[0];  //To change body of implemented methods 
use File | Settings | File Templates.
  |   |         }
  |   | 
  |   |         public void rollback(Xid xid) throws XAException {
  |   |             boolean flag = false;
  |   |             if (flag) {
  |   |                 throw new XAException(XAException.XAER_RMERR );
  |   |             }
  |   |         }
  |   | 
  |   |         public boolean setTransactionTimeout(int i) throws XAException {
  |   |             return false;  //To change body of implemented methods use 
File | Settings | File Templates.
  |   |         }
  |   | 
  |   |         public void start(Xid xid, int flags) throws XAException {
  |   |             if (xid == null) throw new 
XAException(XAException.XAER_INVAL);
  |   |             if (managedXid != null) {
  |   |              throw new XAException(XAException.XAER_INVAL);
  |   |             } else {
  |   |                 managedXid = xid;
  |   |             }
  |   |             log.info("Nummer 1:start called " + xid + " i " +flags);
  |   |         }
  |   |     }
  |   | 
  |   | 
  | 
  | as you can see in commit there is always an XAException being thrown.
  | 
  | here is some logging
  | 
  | 
  |   | 11:40:15,195 INFO  [CMRTestFacadeBean] Nummer 1:Error during commit
  |   | 11:40:15,196 WARN  [TransactionImpl] XAException: 
tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=toaster/15, BranchQual=, 
localId=15] errorCode=XA_HEURRB
  |   | javax.transaction.xa.XAException
  |   | at 
eval.cmr.CMRTestFacadeBean$MyXAResource.commit(CMRTestFacadeBean.java:313)action.xa.XAException
  |   | at 
org.jboss.tm.TransactionImpl$Resource.commit(TransactionImpl.java:2253)
  |   |         at 
org.jboss.tm.TransactionImpl.commitResources(TransactionImpl.java:1784)
  |   |         at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:358)
  |   | ...
  |   | 11:40:15,209 INFO  [CMRTestFacadeBean] Nummer 1:forget transcation 
XidImpl[FormatId=257, GlobalId=toaster/15, BranchQual=1, localId=15]
  |   | 11:40:15,242 ERROR [LogInterceptor] TransactionRolledbackException in 
method: public abstract void eval.cmr.CMRTestFacade.jtaTest() throws 
javax.ejb.CreateException,java.rmi.RemoteException, causedBy:
  |   | javax.transaction.HeuristicRollbackException
  |   |         at 
org.jboss.tm.TransactionImpl.checkHeuristics(TransactionImpl.java:1610)
  |   |         at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:378)
  |   |         at 
org.jboss.ejb.plugins.TxInterceptorCMT.endTransaction(TxInterceptorCMT.java:501)
  |   |         at 
org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:361)
  |   |         at 
org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:181)
  |   |         at 
org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:168)
  |   | 
  |   | 
  |   | 
  | 
  | The address which is created is however being written to the Database.
  | 
  | Is that normal?
  | 
  | Thanks in advance 
  | Greetings
  | PeeR
  | 

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

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4044224
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to