
com.sun.messaging.jmq.jmsclient.XAResourceMapForRAMC Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 1997, 2017 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2022 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package com.sun.messaging.jmq.jmsclient;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import javax.transaction.xa.XAException;
import com.sun.messaging.jmq.util.XidImpl;
/**
* This class keeps track of all the XAResourceForMC and XAResourceForRA objects which are party to a given transaction
* branch
*
* This class maintains a static Map whose key is the transaction branch XID (a XidImpl) and whose corresponding value
* is a Set of all the XAResourceForMC and XAResourceForRA objects which are being used in this transaction branch
*
* A resource should be registered with this class by calling register(), whenever XAResource.start(xid,TMNOFLAGS) or
* XAResource.start(xid,TMJOIN) is called and removed from this class when the xid is committed or rolled back.
*
* register() should never be called for XAResource.start(xid,TMRESUME) - this will cause an XAException
*
* Note that the XA spec requires that when a second resource is added to an existing xid, XAStart(xid,flags) is called
* with the join flag set
*
* Note that although this class uses the interface XAResourceForJMQ to refer to instances of XAResourceForMC and
* XAResourceForRA, it is not intended to be used by XAResourceImpl objects, even though that class implements
* XAResourceForJMQ
*
*/
public class XAResourceMapForRAMC {
private static HashMap> resourceMap = new HashMap<>();
public static synchronized void register(XidImpl xid, XAResourceForJMQ xar, boolean isJoin) throws XAException {
Set resources = resourceMap.get(xid);
if (resources == null) {
// xid not found: check we are not doing a join
if (isJoin) {
XAException xae = new XAException("Trying to add an XAResource using the JOIN flag when no existing XAResource has been added with this XID");
xae.errorCode = XAException.XAER_INVAL;
throw xae;
}
resources = new HashSet<>();
resourceMap.put(xid, resources);
} else {
// map already contains an entry for this xid: check we are doing a JOIN
if (!isJoin) {
XAException xae = new XAException("Trying to add an XAResource to an existing xid without using the JOIN flag");
xae.errorCode = XAException.XAER_DUPID;
throw xae;
}
}
resources.add(xar);
}
/**
* Unregister the specified transaction branch and all its resources
*
* This should be called when the transaction is committed or rolled back
*
* @param xid Transaction branch XID
*/
public static synchronized void unregister(XidImpl xid) {
// note that xid won't exist in the map if we obtained this xid using XAResource.recover(),
// so it is not an error if xid is not found
resourceMap.remove(xid);
}
/**
* Unregister the specified resource from the specified transaction branch
*
* This should be called when an individual session is closed but a transaction is still pending
*
* @param xid Transaction branch XID
* @param xar Resource
*/
public static synchronized void unregisterResource(XAResourceForJMQ xar, XidImpl xid) {
Set resources = resourceMap.get(xid);
if (resources != null) {
resources.remove(xar);
if (resources.isEmpty()) {
resourceMap.remove(xid);
}
}
}
/**
* Returns a Set of resources associated with the specified transaction branch
*
* @param xid Transaction branch XID
* @param throwExceptionIfNotFound Whether to throw an exception if XID not found (typically set to true on a commit,
* false on a rollback, since a commit legitimately be followed by a rollback)
* @return Resources associated with the specified transaction branch
* @throws XAException Unknown XID (only thrown if throwExceptionIfNotFound=true)
*/
public static synchronized XAResourceForJMQ[] getXAResources(XidImpl xid, boolean throwExceptionIfNotFound) throws XAException {
Set resources = resourceMap.get(xid);
if (resources == null) {
if (throwExceptionIfNotFound) {
XAException xae = new XAException("Unknown XID (was start() called?");
throw xae;
} else {
return new XAResourceForJMQ[0];
}
}
return resources.toArray(new XAResourceForJMQ[resources.size()]);
}
/**
* Return whether the resources map is empty
*
* This is for use by tests
*/
public static boolean isEmpty() {
return resourceMap.isEmpty();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy