All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mq5.0-source.main.mq-client.src.main.java.com.sun.messaging.jmq.jmsclient.JMSXAWrappedXAResourceImpl Maven / Gradle / Ivy

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2000-2012 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

/*
 * @(#)JMSXAWrappedXAResourceImpl.java	1.8 06/27/07
 */ 

package com.sun.messaging.jmq.jmsclient;

import javax.jms.*;
import javax.transaction.xa.*;
import java.util.StringTokenizer;
import java.util.NoSuchElementException;
import com.sun.jms.spi.xa.*;
import com.sun.messaging.AdministeredObject;


/**
  * JMSXAWrappedXAResourceImpl 
  *
  * 

The XAResource interface is a Java mapping of the industry standard * XA interface based on the X/Open CAE Specification (Distributed * Transaction Processing: The XA Specification). * *

The XA interface defines the contract between a Resource Manager * and a Transaction Manager in a distributed transaction processing * (DTP) environment. A JDBC driver or a JMS provider implements * this interface to support the association between a global transaction * and a database or message service connection. * *

The XAResource interface can be supported by any transactional * resource that is intended to be used by application programs in an * environment where transactions are controlled by an external * transaction manager. An example of such a resource is a database * management system. An application may access data through multiple * database connections. Each database connection is enlisted with * the transaction manager as a transactional resource. The transaction * manager obtains an XAResource for each connection participating * in a global transaction. The transaction manager uses the * start method * to associate the global transaction with the resource, and it uses the * end method to disassociate the transaction from * the resource. The resource * manager is responsible for associating the global transaction to all * work performed on its data between the start and end method invocations. * *

At transaction commit time, the resource managers are informed by * the transaction manager to prepare, commit, or rollback a transaction * according to the two-phase commit protocol.

* * @see javax.transaction.xa.XAResource */ public class JMSXAWrappedXAResourceImpl implements XAResource { private final static boolean debug = JMSXAWrappedConnectionFactoryImpl.debug; private XAResource xar; private JMSXAConnectionFactory cf = null; private boolean isQueue; private String username = null; private String password = null; private boolean closed = false; private JMSXAWrappedTransactionListener listener = null; public JMSXAWrappedXAResourceImpl(XAResource xar, boolean isQueue, JMSXAConnectionFactory cf, String username, String password) { this.xar = xar; this.cf = cf; this.isQueue = isQueue; this.username = username; this.password = password; } protected void setTransactionListener(JMSXAWrappedTransactionListener l) { listener = l; } protected void close() { closed = true; } /** * Commits the global transaction specified by xid. * * @param foreignXid A global transaction identifier * * @param onePhase If true, the resource manager should use a one-phase * commit protocol to commit the work done on behalf of xid. * * @exception XAException An error has occurred. Possible XAExceptions * are XA_HEURHAZ, XA_HEURCOM, XA_HEURRB, XA_HEURMIX, XAER_RMERR, * XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or XAER_PROTO. * *

If the resource manager did not commit the transaction and the * parameter onePhase is set to true, the resource manager may throw * one of the XA_RB* exceptions. Upon return, the resource manager has * rolled back the branch's work and has released all held resources. */ public void commit(Xid foreignXid, boolean onePhase) throws XAException { if (!closed || xar instanceof com.sun.messaging.jmq.jmsclient.XAResourceImpl) { dlog("commit(Xid="+foreignXid+" onePhase="+onePhase+"), closed="+closed); boolean completed = false; try { if (listener != null) listener.beforeTransactionComplete(); xar.commit(foreignXid, onePhase); completed = true; } catch (XAException e ) { switch (e.errorCode) { case XAException.XA_HEURHAZ: case XAException.XA_HEURCOM: case XAException.XA_HEURRB: case XAException.XA_HEURMIX: completed = false; /* wait forget */ break; case XAException.XA_RETRY: completed = false; /* allowed only for 2-phase commit */ break; case XAException.XA_RBROLLBACK: case XAException.XA_RBCOMMFAIL: case XAException.XA_RBDEADLOCK: case XAException.XA_RBINTEGRITY: case XAException.XA_RBOTHER: case XAException.XA_RBPROTO: case XAException.XA_RBTIMEOUT: case XAException.XA_RBTRANSIENT: completed = true; /* allowed only for 1-phase commit */ break; case XAException.XAER_RMFAIL: case XAException.XAER_NOTA: /* ?? */ case XAException.XAER_INVAL: /* ?? */ case XAException.XAER_PROTO: default: completed = true; } throw e; } finally { if (listener != null) listener.afterTransactionComplete(foreignXid, completed); } } else { JMSXAConnection c = null; try { dlog("closed commit() ..."); c = getConnection(); XAResource r = getXAResource(c); dlog("closed commit(Xid="+foreignXid+" onePhase="+onePhase+")"); r.commit(foreignXid, onePhase); } catch (JMSException e) { log("Error:", e); throw new XAException(XAException.XAER_RMFAIL); } finally { if (c != null) { try { c.close(); } catch (Exception e) { log(AdministeredObject.cr.getKString(AdministeredObject.cr.W_WARNING), "commit():Connection.close(): " + e.getMessage()); } } } } } /** * Ends the work performed on behalf of a transaction branch. * The resource manager disassociates the XA resource from the * transaction branch specified and lets the transaction * complete. * *

If TMSUSPEND is specified in the flags, the transaction branch * is temporarily suspended in an incomplete state. The transaction * context is in a suspended state and must be resumed via the * start method with TMRESUME specified.

* *

If TMFAIL is specified, the portion of work has failed. * The resource manager may mark the transaction as rollback-only

* *

If TMSUCCESS is specified, the portion of work has completed * successfully.

* * @param foreignXid A global transaction identifier that is the same as * the identifier used previously in the start method. * * @param flags One of TMSUCCESS, TMFAIL, or TMSUSPEND. * * @exception XAException An error has occurred. Possible XAException * values are XAER_RMERR, XAER_RMFAILED, XAER_NOTA, XAER_INVAL, * XAER_PROTO, or XA_RB*. */ public void end(Xid foreignXid, int flags) throws XAException { boolean completed = false; try { if (listener != null) listener.beforeTransactionComplete(); xar.end(foreignXid, flags); } catch (XAException e) { switch(e.errorCode) { case XAException.XA_RBROLLBACK: case XAException.XA_RBCOMMFAIL: case XAException.XA_RBDEADLOCK: case XAException.XA_RBINTEGRITY: case XAException.XA_RBOTHER: case XAException.XA_RBPROTO: case XAException.XA_RBTIMEOUT: case XAException.XA_RBTRANSIENT: completed = false; break; default: completed = true; } throw e; } finally { if (listener != null) listener.afterTransactionComplete(foreignXid, completed); } } /** * Tells the resource manager to forget about a heuristically * completed transaction branch. * * @param foreignXid A global transaction identifier. * * @exception XAException An error has occurred. Possible exception * values are XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or * XAER_PROTO. */ public void forget(Xid foreignXid) throws XAException { if (!closed || xar instanceof com.sun.messaging.jmq.jmsclient.XAResourceImpl) { dlog("forget(Xid="+foreignXid+"), closed="+closed); boolean completed = false; try { if (listener != null) listener.beforeTransactionComplete(); xar.forget(foreignXid); completed = true; } finally { if (listener != null) listener.afterTransactionComplete(foreignXid, completed); } } else { JMSXAConnection c = null; try { dlog("closed forget(Xid="+foreignXid+")"); c = getConnection(); XAResource r = getXAResource(c); r.forget(foreignXid); } catch (JMSException e) { log("Error:", e); throw new XAException(XAException.XAER_RMFAIL); } finally { if (c != null) { try { c.close(); } catch (Exception e) { log(AdministeredObject.cr.getKString(AdministeredObject.cr.W_WARNING), "forget():Connection.close(): " + e.getMessage()); } } } } } /** * Obtains the current transaction timeout value set for this * XAResource instance. If XAResource.setTransactionTimeout * was not used prior to invoking this method, the return value * is the default timeout set for the resource manager; otherwise, * the value used in the previous setTransactionTimeout * call is returned. * * @return the transaction timeout value in seconds. * * @exception XAException An error has occurred. Possible exception * values are XAER_RMERR and XAER_RMFAIL. */ public int getTransactionTimeout() throws XAException { return xar.getTransactionTimeout(); } /** * This method is called to determine if the resource manager * instance represented by the target object is the same as the * resouce manager instance represented by the parameter xares. * * @param foreignXaRes An XAResource object whose resource manager instance * is to be compared with the resource manager instance of the * target object. * * @return true if it's the same RM instance; otherwise * false. * * @exception XAException An error has occurred. Possible exception * values are XAER_RMERR and XAER_RMFAIL. * */ public boolean isSameRM(XAResource foreignXaRes) throws XAException { dlog(xar.getClass().getName()+".isSameRM("+foreignXaRes.getClass().getName()+")"); return xar.isSameRM(foreignXaRes); } /** * Ask the resource manager to prepare for a transaction commit * of the transaction specified in xid. * * @param foreignXid A global transaction identifier. * * @exception XAException An error has occurred. Possible exception * values are: XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL, * or XAER_PROTO. * * @return A value indicating the resource manager's vote on the * outcome of the transaction. The possible values are: XA_RDONLY * or XA_OK. If the resource manager wants to roll back the * transaction, it should do so by raising an appropriate XAException * in the prepare method. */ public int prepare(Xid foreignXid) throws XAException { if (!closed || xar instanceof com.sun.messaging.jmq.jmsclient.XAResourceImpl) { dlog("prepare(Xid="+foreignXid+"), closed="+closed); boolean completed = false; int ret = XA_OK; try { if (listener != null) listener.beforeTransactionComplete(); ret = xar.prepare(foreignXid); if (ret == XA_RDONLY) completed = true; return ret; } catch (XAException e) { switch (e.errorCode) { case XAException.XA_RBROLLBACK: case XAException.XA_RBCOMMFAIL: case XAException.XA_RBDEADLOCK: case XAException.XA_RBINTEGRITY: case XAException.XA_RBOTHER: case XAException.XA_RBPROTO: case XAException.XA_RBTIMEOUT: case XAException.XA_RBTRANSIENT: completed = true; break; default: completed = true; } throw e; } finally { if (listener != null) listener.afterTransactionComplete(foreignXid, completed); } } else { JMSXAConnection c = null; try { dlog("closed prepare(Xid="+foreignXid+")"); c = getConnection(); XAResource r = getXAResource(c); return r.prepare(foreignXid); } catch (JMSException e) { log("Error:", e); throw new XAException(XAException.XAER_RMFAIL); } finally { if (c != null) { try { c.close(); } catch (Exception e) { log(AdministeredObject.cr.getKString(AdministeredObject.cr.W_WARNING), "prepare():Connection.close():" + e.getMessage()); } } } } } /** * Obtains a list of prepared transaction branches from a resource * manager. The transaction manager calls this method during recovery * to obtain the list of transaction branches that are currently in * prepared or heuristically completed states. * * @param flags One of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS. TMNOFLAGS * must be used when no other flags are set in the parameter. * * @exception XAException An error has occurred. Possible values are * XAER_RMERR, XAER_RMFAIL, XAER_INVAL, and XAER_PROTO. * * @return The resource manager returns zero or more XIDs of the * transaction branches that are currently in a prepared or * heuristically completed state. If an error occurs during the * operation, the resource manager should throw the appropriate * XAException. * */ public Xid[] recover(int flags) throws XAException { return xar.recover(flags); } /** * Informs the resource manager to roll back work done on behalf * of a transaction branch. * * @param foreignXid A global transaction identifier. * * @exception XAException An error has occurred. */ public void rollback(Xid foreignXid) throws XAException { if (!closed || xar instanceof com.sun.messaging.jmq.jmsclient.XAResourceImpl) { dlog("rollback(Xid="+foreignXid+"), closed="+closed); boolean completed = false; try { if (listener != null) listener.beforeTransactionComplete(); xar.rollback(foreignXid); completed = true; } catch (XAException e) { switch (e.errorCode) { case XAException.XA_HEURHAZ: case XAException.XA_HEURCOM: case XAException.XA_HEURRB: case XAException.XA_HEURMIX: completed = false; /* wait forget */ break; case XAException.XA_RBROLLBACK: case XAException.XA_RBCOMMFAIL: case XAException.XA_RBDEADLOCK: case XAException.XA_RBINTEGRITY: case XAException.XA_RBOTHER: case XAException.XA_RBPROTO: case XAException.XA_RBTIMEOUT: case XAException.XA_RBTRANSIENT: completed = true; /* typically for tran marked rollback-only */ break; default: completed = true; } throw e; } finally { if (listener != null) listener.afterTransactionComplete(foreignXid, completed); } } else { JMSXAConnection c = null; try { dlog("closed rollback() ..."); c = getConnection(); XAResource r = getXAResource(c); dlog("closed rollback(Xid="+foreignXid+")"); r.rollback(foreignXid); } catch (JMSException e) { log("Error:", e); throw new XAException(XAException.XAER_RMFAIL); } finally { if (c != null) { try { c.close(); } catch (Exception e) { log(AdministeredObject.cr.getKString(AdministeredObject.cr.W_WARNING), "rollback():Connection.close():" + e.getMessage()); } } } } } /** *

Sets the current transaction timeout value for this XAResource * instance. Once set, this timeout value is effective until * setTransactionTimeout is invoked again with a different * value. To reset the timeout value to the default value used by the resource * manager, set the value to zero. * * If the timeout operation is performed successfully, the method returns * true; otherwise false. If a resource manager does not * support explicitly setting the transaction timeout value, this method * returns false. * * @param transactionTimeout The transaction timeout value in seconds. * * @return true if the transaction timeout value is set successfully; * otherwise false. * * @exception XAException An error has occurred. Possible exception values * are XAER_RMERR, XAER_RMFAIL, or XAER_INVAL. */ public boolean setTransactionTimeout(int transactionTimeout) throws XAException { return xar.setTransactionTimeout(transactionTimeout); } /** * Starts work on behalf of a transaction branch specified in * foreignXid. * * If TMJOIN is specified, the start applies to joining a transaction * previously seen by the resource manager. If TMRESUME is specified, * the start applies to resuming a suspended transaction specified in the * parameter foreignXid. * * If neither TMJOIN nor TMRESUME is specified and the transaction * specified by foreignXid has previously been seen by the resource * manager, the resource manager throws the XAException exception with * XAER_DUPID error code. * * @param foreignXid A global transaction identifier to be associated * with the resource. * * @param flags One of TMNOFLAGS, TMJOIN, or TMRESUME. * * @exception XAException An error has occurred. Possible exceptions * are XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_DUPID, XAER_OUTSIDE, * XAER_NOTA, XAER_INVAL, or XAER_PROTO. * */ public void start(Xid foreignXid, int flags) throws XAException { boolean started = false; try { if (listener != null) listener.beforeTransactionStart(); xar.start(foreignXid, flags); /* assume TMJOIN/TMRESUME has a corresponding TMNOFLAGS start * that is, they cause 1 transaction completion */ if (flags == TMNOFLAGS) started = true; } catch (JMSException e) { log("Error:", e); throw new XAException(XAException.XAER_RMFAIL); } catch (XAException e) { switch(e.errorCode) { case XAException.XA_RBROLLBACK: case XAException.XA_RBCOMMFAIL: case XAException.XA_RBDEADLOCK: case XAException.XA_RBINTEGRITY: case XAException.XA_RBOTHER: case XAException.XA_RBPROTO: case XAException.XA_RBTIMEOUT: case XAException.XA_RBTRANSIENT: started = false; /* ??? may cause negative 'transactions' count in Session */ break; default: started = false; } throw e; } finally { if (listener != null) listener.afterTransactionStart(foreignXid, started); } } private JMSXAConnection getConnection() throws JMSException { JMSXAConnection c = null; if (isQueue) { if (username == null) { c = ((JMSXAQueueConnectionFactory)cf).createXAQueueConnection(); } else { c = ((JMSXAQueueConnectionFactory)cf).createXAQueueConnection(username, password); } } else { if (username == null) { c = ((JMSXATopicConnectionFactory)cf).createXATopicConnection(); } else { c = ((JMSXATopicConnectionFactory)cf).createXATopicConnection(username, password); } } return c; } public XAResource getDelegatedXAResource() { return xar; } private XAResource getXAResource(JMSXAConnection c) throws JMSException, XAException { JMSXASession s; if (isQueue) { s = ((JMSXAQueueConnection)c).createXAQueueSession(true, Session.AUTO_ACKNOWLEDGE); } else { s = ((JMSXATopicConnection)c).createXATopicSession(true, Session.AUTO_ACKNOWLEDGE); } XAResource r = s.getXAResource(); String rc = null; if (r instanceof com.sun.messaging.jmq.jmsclient.JMSXAWrappedXAResourceImpl) { rc = ((com.sun.messaging.jmq.jmsclient.JMSXAWrappedXAResourceImpl) r).getDelegatedXAResource().getClass().getName(); } else { rc = r.getClass().getName(); } boolean skip = isSystemPropertySetFor("skipIsSameRMCheckForExternalJMSXAResource", rc); if (r.isSameRM(xar)) { dlog("isSameRM() true - " + xar.getClass().getName()); try { int t = xar.getTransactionTimeout(); if (t >= 0) { r.setTransactionTimeout(t); } } catch (Exception e) { log(AdministeredObject.cr.getKString(AdministeredObject.cr.W_WARNING), "get/setTransactionTimeout(): " +e.getMessage()); } } else { if (!skip) { log("Error:", "isSameRM() false - "+xar.getClass().getName()); throw new XAException(XAException.XAER_RMFAIL); } else { log(AdministeredObject.cr.getKString(AdministeredObject.cr.W_WARNING), "isSameRM() false, ignore. - "+xar.getClass().getName()); } } return r; } public static boolean isSystemPropertySetFor(String propName, String propValue) { boolean isSet = false; String values = System.getProperty(propName); if (values == null) return false; StringTokenizer token = new StringTokenizer(values, ","); try { while (token.hasMoreTokens()) { if (propValue.equals((token.nextToken().trim()))) { isSet = true; break; } } } catch (NoSuchElementException e) {} return isSet; } private final static void dlog(String msg) { if (debug) log("Info:", msg); } private final static void dlogStack(Exception e) { if (debug) e.printStackTrace(); } private final static void log(String level, Exception e) { log(level, e.getMessage()); e.printStackTrace(); } private final static void log(String level, String msg) { System.out.println(level+ " "+ "JMSXAWrappedXAResource: " + msg); } } /**************** @(#)seebeyond.txt 1.9 04/10/17 SeeBeyond's Issue: Session close causing RollbackException on commit in MDB CMT According to SeeBeyond, in its XASession implementation, session close will cause not only local transactions to rollback but also global (XA) transactions to rollback. SeeBeyond claimed that to change their implementation is too risky and is not something they want to consider. To support Sun customer Syntegra, we are planning to provide a workaround in our wrapper classes for AS7 foreign JMS provider to better work with SeeBeyond's JMS implementation. The workaround is to delay session close until a started XA transaction completes. There are possibly 3 approaches to address the problem: 1. Code changes in MQ source in JMS wrapper classes for foreign JMS providers cons: no access to Transaction/TransactionManager objects therefore can't get transaction completion notification using javax.transaction.Synchronization. pros: only need to patch MQ jar file affect only foreign JMS provider support in AS7 2. Code changes in AS7 source in JMS wrapper classes cons: affects MQ integration source in AS7 would need patch AS7 3. Code changes in AS7 source and MQ source pros: scope the change in AS7 source as small as possible cons: would need patch both AS7 and MQ jar file Since we are planning to provide the workaround for only one customer, we are planning to use #1 approach with some limitations. Notes on Modifications on MQ's JMS Wrapper Classes for Foreign JMS Providers --------------------------------------------------------------------------- 1. Transaction completion detection . Use XAResource.commit/rollback (including forget call) calls to detect transaction completion . XAException error codes will also be checked for XAResource.commit/rollback calls to distinguish those XAExceptions that indicates transaction completion and those indicates transaction not completed* limitation: Since we can't use javax.transaction.Synchronization, our transaction completion detection through XAResource object would not be bullet-proof. There can be edge cases where a transaction completion is not detected which would cause Session leak or where a Session can be closed too early due to vagueness in the XA/JTA specs for some edge cases. But it's our understanding that these edge cases should not be common. Understanding SeeBeyond's XA resource manager implementation detail maybe able to help narrow down some of these edge cases. This transaction completion detection also has the assumption that a transaction started on a XAResource object will always be completed on the same XAResource object. We expect SeeBeyond's XAResource implementation meets this requirement since its XAResource.isSameRM always returns false for two different XAResource objects. Since Connection will not be hard-closed until all its Sessions have been hard-closed (see #3), session leak would also lead to connection leak. Therefore applications should provide some connection monitoring/ cleanup mechanism to periodically monitor/cleanup leaked connections if Connection leak does become an issue. *: see more details at XAResource XAException Checks below 2. JMS Session close semantic . Session close is deferred until transaction completes . Session.close is NOT deferred if there is a Session MessageListener . Operations on 'soft-closed' Session will NOT be prevented limitations: . no JMS Session close semantic of throwing IllegalStateException when using the closed Session or its producers/consumers . no JMS Session close semantic of unblocking MessageConsumer.receive . no JMS Session close semantic of waiting MessageConsumer.receive orderly returning the message . no JMS Session close semantic of waiting for all MessageConsumer's MessageListeners return 3. JMS Connection close semantic . Connection close is deferred until all sessions has been hard-closed . Operations (except create XASession) on 'soft-closed' Connection will NOT be prevented . See 'JMS Session close semantic' limitation: . no JMS Connection close semantic of throwing IllegalStateException when using a closed Connection (except create XASession) or its Sessions . no JMS Connection close semantic of only return until message processing has been orderly shut down 4. The Session.close()/Connection.close deferral is turned on by setting following jvm system property delaySessionCloseForExternalJMSXAResource which is a ',' separated list of fully-qualified class name strings that are XAResource implementation classes for an external JMS provider. XAResource XAException Checks ----------------------------- A XASession will only do soft-close if there is any uncompleted XA transaction that has been started on its XAResource (and there is no Session MessageListener set for the XASession). A soft-closed XASession will be hard-closed only when all XA transactions that have started on its XAResource have been completed or if its Connection is closed. 1. XAResource.commit *The transaction will not mark as completed for following XAExceptions: (expecting XAResource.forget to be called later XA spec: A resource manager that heuristically completes work done on behalf of a transaction branch must keep track of that branch along with the decision (that is, heuristically committed, rolled back, or mixed) XA_HEURHAZ XA_HEURCOM XA_HEURRB XA_HEURMIX XA_RETRY (XA spec: All resources held on behalf of *xid remain in a prepared state until commitment is possible.) *The transaction will be marked as completed for following XAExceptions: (XA spec: Upon return the resource manager has rolled back the branch's work and has released all held resources. Only applicable to 1-phase commit) XA_RBROLLBACK XA_RBCOMMFAIL XA_RBDEADLOCK XA_RBINTEGRITY XA_RBOTHER XA_RBPROTO XA_RBTIMEOUT XA_RBTRANSIENT *All other XAExceptions will mark the transaction completion (XA spec: not clear) 2. XAResource.rollback *The transaction will not mark as completed for following XAExceptions: (expecting XAResource.forget to be called later XA spec: A resource manager that heuristically completes work done on behalf of a transaction branch must keep track of that branch along with the decision (that is, heuristically committed, rolled back, or mixed) XA_HEURHAZ XA_HEURCOM XA_HEURRB XA_HEURMIX *The transaction will be marked as completed for following XAExceptions: (XA spec: The resource manager has rolled back the transaction branch's work and has released all held resources. typically occurs when the branch was already marked rollback-only) XA_RBROLLBACK XA_RBCOMMFAIL XA_RBDEADLOCK XA_RBINTEGRITY XA_RBOTHER XA_RBPROTO XA_RBTIMEOUT XA_RBTRANSIENT *All other XAExceptions will mark the transaction completion (CA spec: not clear) 3. XAResource.forget The transaction is marked as completed for any XAExceptions (XA spec: not clear) 4. XAResource.start *A new transaction is not marked as started for XAExceptions: (XA spec: The resource manager has not associated the transaction branch with the thread of control and has marked *xid rollback-only.) XA_RBROLLBACK XA_RBCOMMFAIL XA_RBDEADLOCK XA_RBINTEGRITY XA_RBOTHER XA_RBPROTO XA_RBTIMEOUT XA_RBTRANSIENT *A transaction is not marked as started for any other XAExceptions *If TMJOIN or TMRESUME flag set, it will not mark a new transaction as started regardless it throws XAException or not 5. XAResource.end *The transaction will not be marked as completed for following XAExceptions: (expecting rollback to be called XA spec: The resource manager has dissociated the transaction branch from the thread of control and has marked rollback-only the work performed on behalf of *xid.) XA_RBROLLBACK XA_RBCOMMFAIL XA_RBDEADLOCK XA_RBINTEGRITY XA_RBOTHER XA_RBPROTO XA_RBTIMEOUT XA_RBTRANSIENT *The transaction will be marked as completed for any other XAExceptions (XA spec: not clear) *The transaction is not marked as completed when no XAException 5. XAResource.prepare * The transaction will be marked as completed if returns XA_RDONLY (XA spec: XA_RDONLY - The resource manager may release all resources and forget about the branch. committed) * The transaction will not be marked as completed if returns XA_OK (XA spec: A resource manager cannot erase its knowledge of a branch until the transaction manager calls either commit or rollback) * The transaction will be marked as completed for following XAException: (XA spec: - Upon return, the resource manager has rolled back the branch's work and has released all held resources.) XA_RBROLLBACK XA_RBCOMMFAIL XA_RBDEADLOCK XA_RBINTEGRITY XA_RBOTHER XA_RBPROTO XA_RBTIMEOUT XA_RBTRANSIENT * The transaction will be marked as completed for any other XAException *****************/





© 2015 - 2024 Weber Informatics LLC | Privacy Policy