From 12e0121b392be8fa1707eb5c73d29d55317f813c Mon Sep 17 00:00:00 2001 From: Arnaud Simon Date: Tue, 18 Sep 2007 14:37:09 +0000 Subject: Added XA support (for 0_10 only) git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@576933 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/qpid/client/AMQConnection.java | 2 +- .../apache/qpid/client/AMQConnectionDelegate.java | 6 +- .../qpid/client/AMQConnectionDelegate_0_10.java | 28 +- .../qpid/client/AMQConnectionDelegate_0_8.java | 6 + .../apache/qpid/client/AMQConnectionFactory.java | 178 +++++++- .../org/apache/qpid/client/AMQSession_0_10.java | 12 +- .../qpid/client/BasicMessageConsumer_0_10.java | 2 +- .../org/apache/qpid/client/XAConnectionImpl.java | 78 ++++ .../org/apache/qpid/client/XAResourceImpl.java | 507 +++++++++++++++++++++ .../java/org/apache/qpid/client/XASessionImpl.java | 147 ++++++ 10 files changed, 930 insertions(+), 36 deletions(-) create mode 100644 qpid/java/client/src/main/java/org/apache/qpid/client/XAConnectionImpl.java create mode 100644 qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java create mode 100644 qpid/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java (limited to 'qpid/java') diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java index 86b4807069..1728ab69f7 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java @@ -153,7 +153,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect protected final ExecutorService _taskPool = Executors.newCachedThreadPool(); protected static final long DEFAULT_TIMEOUT = 1000 * 30; - private AMQConnectionDelegate _delegate; + protected AMQConnectionDelegate _delegate; /** * @param broker brokerdetails diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java index eccca87dc2..07bd7ea0ae 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java @@ -23,18 +23,22 @@ package org.apache.qpid.client; import java.io.IOException; import javax.jms.JMSException; +import javax.jms.XASession; import org.apache.qpid.AMQException; import org.apache.qpid.client.failover.FailoverException; import org.apache.qpid.jms.BrokerDetails; +import org.apache.qpid.jms.Session; public interface AMQConnectionDelegate { public void makeBrokerConnection(BrokerDetails brokerDetail) throws IOException, AMQException; - public org.apache.qpid.jms.Session createSession(final boolean transacted, final int acknowledgeMode, + public Session createSession(final boolean transacted, final int acknowledgeMode, final int prefetchHigh, final int prefetchLow) throws JMSException; + public XASession createXASession(int prefetchHigh, int prefetchLow) throws JMSException; + public void resubscribeSessions() throws JMSException, AMQException, FailoverException; public void closeConneciton(long timeout) throws JMSException, AMQException; diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java index 8b6b416f88..cd657570bf 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java @@ -3,6 +3,7 @@ package org.apache.qpid.client; import java.io.IOException; import javax.jms.JMSException; +import javax.jms.XASession; import org.apache.qpid.AMQException; import org.apache.qpid.protocol.AMQConstant; @@ -11,8 +12,6 @@ import org.apache.qpid.jms.BrokerDetails; import org.apache.qpid.jms.Session; import org.apache.qpidity.client.Client; import org.apache.qpidity.QpidException; -import org.apache.qpidity.jms.SessionImpl; -import org.apache.qpidity.jms.ExceptionHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,6 +64,31 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate return session; } + /** + * create an XA Session and start it if required. + */ + public XASession createXASession(int prefetchHigh, int prefetchLow) throws JMSException + { + _conn.checkNotClosed(); + int channelId = _conn._idFactory.incrementAndGet(); + XASessionImpl session; + try + { + session = new XASessionImpl(_qpidConnection, _conn, channelId, prefetchHigh, prefetchLow); + _conn.registerSession(channelId, session); + if (_conn._started) + { + session.start(); + } + } + catch (Exception e) + { + throw new JMSAMQException("cannot create session", e); + } + return session; + } + + /** * Make a connection with the broker * diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_8.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_8.java index 3ad32d83fb..c22fcc3c7a 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_8.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_8.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.Iterator; import javax.jms.JMSException; +import javax.jms.XASession; import org.apache.qpid.AMQException; import org.apache.qpid.client.failover.FailoverException; @@ -101,6 +102,11 @@ public class AMQConnectionDelegate_0_8 implements AMQConnectionDelegate return createSession(transacted, acknowledgeMode, prefetch, prefetch); } + public XASession createXASession(int prefetchHigh, int prefetchLow) throws JMSException + { + throw new UnsupportedOperationException("0_8 version does not provide XA support"); + } + public org.apache.qpid.jms.Session createSession(final boolean transacted, final int acknowledgeMode, final int prefetchHigh, final int prefetchLow) throws JMSException { diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java index 9b0183967d..dfc87e21b1 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java @@ -24,13 +24,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Hashtable; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSException; -import javax.jms.QueueConnection; -import javax.jms.QueueConnectionFactory; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; +import javax.jms.*; import javax.naming.Context; import javax.naming.Name; import javax.naming.NamingException; @@ -45,7 +39,9 @@ import org.apache.qpid.url.AMQBindingURL; import org.apache.qpid.url.URLSyntaxException; -public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, ObjectFactory, Referenceable +public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, + ObjectFactory, Referenceable, XATopicConnectionFactory, + XAQueueConnectionFactory, XAConnectionFactory { private String _host; private int _port; @@ -77,18 +73,17 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF _connectionDetails = url; } - /** + /** * This constructor is never used! */ - public AMQConnectionFactory(String broker, String username, String password, - String clientName, String virtualHost) throws URLSyntaxException + public AMQConnectionFactory(String broker, String username, String password, String clientName, String virtualHost) + throws URLSyntaxException { - this(new AMQConnectionURL(ConnectionURL.AMQ_PROTOCOL + "://" + - username + ":" + password + "@" + clientName + "/" + - virtualHost + "?brokerlist='" + broker + "'")); + this(new AMQConnectionURL( + ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@" + clientName + "/" + virtualHost + "?brokerlist='" + broker + "'")); } - /** + /** * This constructor is never used! */ public AMQConnectionFactory(String host, int port, String virtualPath) @@ -96,7 +91,7 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF this(host, port, "guest", "guest", virtualPath); } - /** + /** * This constructor is never used! */ public AMQConnectionFactory(String host, int port, String defaultUsername, String defaultPassword, @@ -144,17 +139,21 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF /** * Getter for SSLConfiguration + * * @return SSLConfiguration if set, otherwise null */ - public final SSLConfiguration getSSLConfiguration() { + public final SSLConfiguration getSSLConfiguration() + { return _sslConfig; } /** * Setter for SSLConfiguration + * * @param sslConfig config to store */ - public final void setSSLConfiguration(SSLConfiguration sslConfig) { + public final void setSSLConfiguration(SSLConfiguration sslConfig) + { _sslConfig = sslConfig; } @@ -355,8 +354,7 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF * @return AMQConnection,AMQTopic,AMQQueue, or AMQConnectionFactory. * @throws Exception */ - public Object getObjectInstance(Object obj, Name name, Context ctx, - Hashtable env) throws Exception + public Object getObjectInstance(Object obj, Name name, Context ctx, Hashtable env) throws Exception { if (obj instanceof Reference) { @@ -409,10 +407,140 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF public Reference getReference() throws NamingException { - return new Reference( - AMQConnectionFactory.class.getName(), - new StringRefAddr(AMQConnectionFactory.class.getName(), _connectionDetails.getURL()), - AMQConnectionFactory.class.getName(), - null); // factory location + return new Reference(AMQConnectionFactory.class.getName(), + new StringRefAddr(AMQConnectionFactory.class.getName(), _connectionDetails.getURL()), + AMQConnectionFactory.class.getName(), null); // factory location + } + + // --------------------------------------------------------------------------------------------------- + // the following methods are provided for XA compatibility + // Those methods are only supported by 0_10 and above + // --------------------------------------------------------------------------------------------------- + + /** + * Creates a XAConnection with the default user identity. + *

The XAConnection is created in stopped mode. No messages + * will be delivered until the Connection.start method + * is explicitly called. + * + * @return A newly created XAConnection + * @throws JMSException If creating the XAConnection fails due to some internal error. + * @throws JMSSecurityException If client authentication fails due to an invalid user name or password. + */ + public XAConnection createXAConnection() throws JMSException + { + if (_connectionDetails.getURLVersion() == ConnectionURL.URL_0_8) + { + throw new UnsupportedOperationException("This version does not support XA operations"); + } + else + { + try + { + return new XAConnectionImpl(_connectionDetails, _sslConfig); + } + catch (Exception e) + { + JMSException jmse = new JMSException("Error creating connection: " + e.getMessage()); + jmse.setLinkedException(e); + throw jmse; + } + } + } + + /** + * Creates a XAConnection with the specified user identity. + *

The XAConnection is created in stopped mode. No messages + * will be delivered until the Connection.start method + * is explicitly called. + * + * @param username the caller's user name + * @param password the caller's password + * @return A newly created XAConnection. + * @throws JMSException If creating the XAConnection fails due to some internal error. + * @throws JMSSecurityException If client authentication fails due to an invalid user name or password. + */ + public XAConnection createXAConnection(String username, String password) throws JMSException + { + if (_connectionDetails != null) + { + _connectionDetails.setUsername(username); + _connectionDetails.setPassword(password); + + if (_connectionDetails.getClientName() == null || _connectionDetails.getClientName().equals("")) + { + _connectionDetails.setClientName(getUniqueClientID()); + } + } + else + { + throw new JMSException("A URL must be specified to access XA connections"); + } + return createXAConnection(); + } + + + /** + * Creates a XATopicConnection with the default user identity. + *

The XATopicConnection is created in stopped mode. No messages + * will be delivered until the Connection.start method + * is explicitly called. + * + * @return A newly created XATopicConnection + * @throws JMSException If creating the XATopicConnection fails due to some internal error. + * @throws JMSSecurityException If client authentication fails due to an invalid user name or password. + */ + public XATopicConnection createXATopicConnection() throws JMSException + { + return (XATopicConnection) createXAConnection(); + } + + /** + * Creates a XATopicConnection with the specified user identity. + *

The XATopicConnection is created in stopped mode. No messages + * will be delivered until the Connection.start method + * is explicitly called. + * + * @param username the caller's user name + * @param password the caller's password + * @return A newly created XATopicConnection. + * @throws JMSException If creating the XATopicConnection fails due to some internal error. + * @throws JMSSecurityException If client authentication fails due to an invalid user name or password. + */ + public XATopicConnection createXATopicConnection(String username, String password) throws JMSException + { + return (XATopicConnection) createXAConnection(username, password); + } + + /** + * Creates a XAQueueConnection with the default user identity. + *

The XAQueueConnection is created in stopped mode. No messages + * will be delivered until the Connection.start method + * is explicitly called. + * + * @return A newly created XAQueueConnection + * @throws JMSException If creating the XAQueueConnection fails due to some internal error. + * @throws JMSSecurityException If client authentication fails due to an invalid user name or password. + */ + public XAQueueConnection createXAQueueConnection() throws JMSException + { + return (XAQueueConnection) createXAConnection(); + } + + /** + * Creates a XAQueueConnection with the specified user identity. + *

The XAQueueConnection is created in stopped mode. No messages + * will be delivered until the Connection.start method + * is explicitly called. + * + * @param username the caller's user name + * @param password the caller's password + * @return A newly created XAQueueConnection. + * @throws JMSException If creating the XAQueueConnection fails due to some internal error. + * @throws JMSSecurityException If client authentication fails due to an invalid user name or password. + */ + public XAQueueConnection createXAQueueConnection(String username, String password) throws JMSException + { + return (XAQueueConnection) createXAConnection(username, password); } } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java index c14b10903c..995f84bab9 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java @@ -80,15 +80,15 @@ public class AMQSession_0_10 extends AMQSession * @param defaultPrefetchHighMark The maximum number of messages to prefetched before suspending the session. * @param defaultPrefetchLowMark The number of prefetched messages at which to resume the session. */ - AMQSession_0_10( org.apache.qpidity.client.Connection qpidConnection, AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, - MessageFactoryRegistry messageFactoryRegistry, int defaultPrefetchHighMark, - int defaultPrefetchLowMark) + AMQSession_0_10(org.apache.qpidity.client.Connection qpidConnection, AMQConnection con, int channelId, + boolean transacted, int acknowledgeMode, MessageFactoryRegistry messageFactoryRegistry, + int defaultPrefetchHighMark, int defaultPrefetchLowMark) { super(con, channelId, transacted, acknowledgeMode, messageFactoryRegistry, defaultPrefetchHighMark, defaultPrefetchLowMark); // create the qpid session with an expiry <= 0 so that the session does not expire - _qpidSession = qpidConnection.createSession(0); + _qpidSession = qpidConnection.createSession(0); // set the exception listnere for this session _qpidSession.setExceptionListener(new QpidSessionExceptionListener()); // set transacted if required @@ -108,8 +108,8 @@ public class AMQSession_0_10 extends AMQSession * @param defaultPrefetchHigh The maximum number of messages to prefetched before suspending the session. * @param defaultPrefetchLow The number of prefetched messages at which to resume the session. */ - AMQSession_0_10(org.apache.qpidity.client.Connection qpidConnection, AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, int defaultPrefetchHigh, - int defaultPrefetchLow) + AMQSession_0_10(org.apache.qpidity.client.Connection qpidConnection, AMQConnection con, int channelId, + boolean transacted, int acknowledgeMode, int defaultPrefetchHigh, int defaultPrefetchLow) { this(qpidConnection, con, channelId, transacted, acknowledgeMode, MessageFactoryRegistry.newDefaultRegistry(), diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java index af4905710b..7876cc8e49 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java @@ -79,7 +79,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer future = ((AMQSession_0_10) getSession()).getQpidSession() .exchangeQuery(message.getMessageProperties().getReplyTo().getExchangeName()); diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/XAConnectionImpl.java b/qpid/java/client/src/main/java/org/apache/qpid/client/XAConnectionImpl.java new file mode 100644 index 0000000000..23d5c7bd62 --- /dev/null +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/XAConnectionImpl.java @@ -0,0 +1,78 @@ +/* Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.client; + +import org.apache.qpid.jms.ConnectionURL; +import org.apache.qpid.AMQException; + +import javax.jms.*; + +/** + * This class implements the javax.jms.XAConnection interface + */ +public class XAConnectionImpl extends AMQConnection implements XAConnection, XAQueueConnection, XATopicConnection +{ + //-- constructor + /** + * Create a XAConnection from a connectionURL + */ + public XAConnectionImpl(ConnectionURL connectionURL, SSLConfiguration sslConfig) throws AMQException + { + super(connectionURL, sslConfig); + } + + //-- interface XAConnection + /** + * Creates an XASession. + * + * @return A newly created XASession. + * @throws JMSException If the XAConnectiono fails to create an XASession due to + * some internal error. + */ + public synchronized XASession createXASession() throws JMSException + { + checkNotClosed(); + return _delegate.createXASession(AMQSession.DEFAULT_PREFETCH_HIGH_MARK, AMQSession.DEFAULT_PREFETCH_HIGH_MARK); + } + + //-- Interface XAQueueConnection + /** + * Creates an XAQueueSession. + * + * @return A newly created XASession. + * @throws JMSException If the XAQueueConnectionImpl fails to create an XASession due to + * some internal error. + */ + public XAQueueSession createXAQueueSession() throws JMSException + { + return (XAQueueSession) createXASession(); + } + + //-- Interface XATopicConnection + /** + * Creates an XAQueueSession. + * + * @return A newly created XASession. + * @throws JMSException If the XAQueueConnectionImpl fails to create an XASession due to + * some internal error. + */ + public XATopicSession createXATopicSession() throws JMSException + { + return (XATopicSession) createXASession(); + } +} diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java b/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java new file mode 100644 index 0000000000..c28a150a32 --- /dev/null +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java @@ -0,0 +1,507 @@ +/* Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.client; + +import javax.transaction.xa.XAException; +import javax.transaction.xa.XAResource; +import javax.transaction.xa.Xid; + +import org.apache.qpidity.QpidException; +import org.apache.qpidity.dtx.XidImpl; +import org.apache.qpidity.transport.*; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This is an implementation of javax.jms.XAResource. + */ +public class XAResourceImpl implements XAResource +{ + /** + * this XAResourceImpl's logger + */ + private static final Logger _logger = LoggerFactory.getLogger(XAResourceImpl.class); + + /** + * Reference to the associated XASession + */ + private XASessionImpl _xaSession = null; + + /** + * The XID of this resource + */ + private Xid _xid; + + //--- constructor + + /** + * Create an XAResource associated with a XASession + * + * @param xaSession The session XAresource + */ + protected XAResourceImpl(XASessionImpl xaSession) + { + _xaSession = xaSession; + } + + //--- The XAResource + /** + * Commits the global transaction specified by xid. + * + * @param xid A global transaction identifier + * @param b If true, use a one-phase commit protocol to commit the work done on behalf of xid. + * @throws XAException An error has occurred. 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. + */ + public void commit(Xid xid, boolean b) throws XAException + { + if (_logger.isDebugEnabled()) + { + _logger.debug("commit ", xid); + } + if (xid == null) + { + throw new XAException(XAException.XAER_PROTO); + } + Future future; + try + { + future = _xaSession.getQpidSession() + .dtxCoordinationCommit(XidImpl.convertToString(xid), b ? Option.ONE_PHASE : Option.NO_OPTION); + } + catch (QpidException e) + { + if (_logger.isDebugEnabled()) + { + _logger.debug("Cannot convert Xid into String format ", e); + } + throw new XAException(XAException.XAER_PROTO); + } + // now wait on the future for the result + DtxCoordinationCommitResult result = future.get(); + int status = result.getStatus(); + switch (status) + { + case Constant.XA_OK: + // do nothing this ok + break; + case Constant.XA_HEURHAZ: + throw new XAException(XAException.XA_HEURHAZ); + case Constant.XA_HEURCOM: + throw new XAException(XAException.XA_HEURCOM); + case Constant.XA_HEURRB: + throw new XAException(XAException.XA_HEURRB); + case Constant.XA_HEURMIX: + throw new XAException(XAException.XA_HEURMIX); + case Constant.XA_RBROLLBACK: + throw new XAException(XAException.XA_RBROLLBACK); + case Constant.XA_RBTIMEOUT: + throw new XAException(XAException.XA_RBTIMEOUT); + default: + // this should not happen + if (_logger.isDebugEnabled()) + { + _logger.debug("got unexpected status value: ", status); + } + throw new XAException(XAException.XAER_PROTO); + } + } + + /** + * 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. + *