use of com.sun.messaging.jmq.util.JMQXid in project openmq by eclipse-ee4j.
the class XAResourceImpl method forget.
/**
* 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.
*/
@Override
public void forget(Xid foreignXid) throws XAException {
// iMQ does not support heuristically completed transaction branches
// This is a NOP
// convert to jmq xid
// JMQXid jmqXid = new JMQXid(foreignXid);
// Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:forget:txid=\n"+jmqXid.toString());
// Despite the above, clean up currentJMQXid and the XAResourceMap
JMQXid jmqXid = new JMQXid(foreignXid);
XAResourceMap.unregister(jmqXid);
if (currentJMQXid != null) {
if (currentJMQXid.equals(jmqXid)) {
currentJMQXid = null;
connectionConsumer = null;
clearTransactionInfo();
}
}
}
use of com.sun.messaging.jmq.util.JMQXid in project openmq by eclipse-ee4j.
the class XAResourceImpl method commit.
/**
* 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.
*
* <P>
* 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.
*/
@Override
public void commit(Xid foreignXid, boolean onePhase) throws XAException {
boolean insyncstate = false;
boolean checkrollback = false;
boolean rbrollback = false;
Exception rbrollbackex = null;
if (_logger.isLoggable(Level.FINE)) {
_logger.fine(_lgrPrefix + "(" + this.hashCode() + ") Commit " + printXid(foreignXid) + " (onePhase=" + onePhase + ")");
}
// convert to jmq xid
JMQXid jmqXid = new JMQXid(foreignXid);
if (Debug.debug) {
Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:commit:onePhase=" + onePhase + "\txid=\n" + jmqXid.toString());
}
// HACC
if (this._session.isRollbackOnly) {
Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:prepare:forcing Rollback due to:" + this._session.rollbackCause.getMessage());
// Debug.printStackTrace(this._session.rollbackCause);
XAException xae = new XAException(XAException.XAER_RMFAIL);
xae.initCause(this._session.rollbackCause);
throw xae;
}
try {
try {
// Re-open if needed
// _connection.openConnection(true);
// Bug6664278 - must synced
_connection.openConnectionFromRA(true);
} catch (Exception oce) {
// For now-retry once after a sec
try {
Thread.sleep(1000);
} catch (Exception e) {
}
// _connection.openConnection(true);
// Bug6664278 - must synced
_connection.openConnectionFromRA(true);
}
if (_transaction == null) {
if (Debug.debug) {
Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:commit:using 0 as txnID");
}
if (_connection.isConnectedToHABroker) {
HACommit(foreignXid, jmqXid, onePhase, insyncstate);
} else {
try {
_connection.getProtocolHandler().commit(0L, (onePhase ? XAResource.TMONEPHASE : XAResource.TMNOFLAGS), jmqXid);
} catch (JMSException e) {
if (onePhase) {
checkrollback = true;
}
throw e;
}
}
} else {
if (Debug.debug) {
Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:commit:using real txnID");
}
// Setup protocol Handler
_transaction.setProtocolHandler(_connection.getProtocolHandler());
// Need to ack msgs if this session has not been closed.
if (!_session.isClosed) {
// set sync flag
_session.setInSyncState();
insyncstate = true;
// ack all messages received in this session
_session.receiveCommit();
}
// Perform XA commit
if (this._connection.isConnectedToHABroker) {
this.HACommit(foreignXid, jmqXid, onePhase, insyncstate);
_session.clearUnackedMessageQ();
} else {
try {
_transaction.commitXATransaction(jmqXid, onePhase);
} catch (JMSException e) {
if (onePhase) {
checkrollback = true;
}
throw e;
}
}
}
// _connection.closeConnection();
// Bug6664278 - must synced
_connection.closeConnectionFromRA();
return;
} catch (Exception jmse) {
// Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:commitXAException");
Debug.printStackTrace(jmse);
if (jmse instanceof XAException) {
throw (XAException) jmse;
}
if (jmse instanceof RemoteAcknowledgeException) {
if (checkrollback) {
rbrollbackex = jmse;
rbrollback = true;
}
}
if (!rbrollback && checkrollback && (jmse instanceof JMSException)) {
if (((JMSException) jmse).getErrorCode().equals(ClientResources.X_SERVER_ERROR)) {
Exception e1 = ((JMSException) jmse).getLinkedException();
if (e1 instanceof JMSException && !((JMSException) e1).getErrorCode().equals(Status.getString(Status.NOT_FOUND))) {
SessionImpl.sessionLogger.log(Level.WARNING, "Exception on 1-phase commit transaction " + jmqXid + ", will rollback", jmse);
rbrollbackex = jmse;
rbrollback = true;
}
}
}
if (!rbrollback) {
XAException xae = new XAException(XAException.XAER_RMFAIL);
xae.initCause(jmse);
throw xae;
}
} finally {
if (!rbrollback) {
// finish up this resource and any others joined to it in this transaction
boolean throwExceptionIfNotFound = false;
XAResourceImpl[] resources = XAResourceMap.getXAResources(jmqXid, throwExceptionIfNotFound);
for (int i = 0; i < resources.length; i++) {
XAResourceImpl xari = resources[i];
xari.clearTransactionInfo();
xari.finishCommit();
}
XAResourceMap.unregister(jmqXid);
}
if (insyncstate) {
_session.releaseInSyncState();
}
}
XAException xae;
try {
rollback(foreignXid);
lastInternalRBCache.put(this, jmqXid);
lastInternalRB = true;
xae = new XAException(XAException.XA_RBROLLBACK);
xae.initCause(rbrollbackex);
} catch (Throwable t) {
SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on rollback transaction " + jmqXid + " after 1-phase-commit failure", t);
xae = new XAException(XAException.XAER_RMFAIL);
xae.initCause(rbrollbackex);
}
throw xae;
}
use of com.sun.messaging.jmq.util.JMQXid in project openmq by eclipse-ee4j.
the class XAResourceImpl method end.
/**
* 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.
*
* <p>
* 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 <code>start</code> method with TMRESUME
* specified.
* </p>
*
* <p>
* If TMFAIL is specified, the portion of work has failed. The resource manager may mark the transaction as
* rollback-only
* </p>
*
* <p>
* If TMSUCCESS is specified, the portion of work has completed successfully.
* </p>
*
* @param foreignXid A global transaction identifier that is the same as the identifier used previously in the
* <code>start</code> 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*.
*/
@Override
public void end(Xid foreignXid, int flags) throws XAException {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine(_lgrPrefix + "XAResourceImpl (" + this.hashCode() + ") End " + printXid(foreignXid) + printFlags(flags));
}
// convert to jmq xid
JMQXid jmqXid = new JMQXid(foreignXid);
if (_connection._isClosed()) {
// Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:end:XAException");
XAException xae = new XAException(XAException.XAER_RMFAIL);
throw xae;
}
// update the resource state
if (isFail(flags)) {
resourceState = FAILED;
} else if (isSuspend(flags)) {
resourceState = INCOMPLETE;
} else {
resourceState = COMPLETE;
}
// END packet, a noop END packet or to ignore the END packet altogether.
if (resourceState == COMPLETE) {
// This XAResource is complete. Send a real END packet if all
// other resources joined to this txn are complete, otherwise
// send a noop END packet to ensure that work associated with
// this XAResource has completed on the broker. See bug 12364646.
boolean allComplete = true;
XAResourceImpl[] resources = XAResourceMap.getXAResources(jmqXid, false);
for (int i = 0; i < resources.length; i++) {
XAResourceImpl xari = resources[i];
if (!xari.isComplete()) {
allComplete = false;
}
}
if (allComplete) {
// All resources complete. Send real END packet.
sendEndToBroker(flags, false, jmqXid);
} else {
// One or more resources are not complete. Send a noop END
// packet to the broker.
sendEndToBroker(flags, true, jmqXid);
}
} else if (resourceState == FAILED) {
// This resource has failed. Send a real END packet regardless
// of the state of any other joined resources.
sendEndToBroker(flags, false, jmqXid);
} else if (resourceState == INCOMPLETE) {
// Don't send the END to the broker. See Glassfish issue 7118.
}
}
use of com.sun.messaging.jmq.util.JMQXid in project openmq by eclipse-ee4j.
the class SessionOp method close.
@Override
public void close(Connection conn) {
TransactionList[] tls = DL.getTransactionList(((IMQConnection) conn).getPartitionedStore());
TransactionList translist = tls[0];
// deal w/ old messages
synchronized (deliveredMessages) {
if (!deliveredMessages.isEmpty()) {
// get the list by IDs
HashMap openMsgs = new HashMap();
Iterator itr = deliveredMessages.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry entry = (Map.Entry) itr.next();
ackEntry e = (ackEntry) entry.getValue();
ConsumerUID cuid = e.getConsumerUID();
ConsumerUID storeduid = (e.getStoredUID() == null ? cuid : e.getStoredUID());
// deal w/ orphan messages
TransactionUID tid = e.getTUID();
if (tid != null) {
JMQXid jmqxid = translist.UIDToXid(tid);
if (jmqxid != null) {
translist.addOrphanAck(tid, e.getSysMessageID(), storeduid, cuid);
itr.remove();
continue;
}
TransactionState ts = translist.retrieveState(tid, true);
if (ts != null && ts.getState() == TransactionState.PREPARED) {
translist.addOrphanAck(tid, e.getSysMessageID(), storeduid, cuid);
itr.remove();
continue;
}
if (ts != null && ts.getState() == TransactionState.COMMITTED) {
itr.remove();
continue;
}
if (ts != null && ts.getState() == TransactionState.COMPLETE && conn.getConnectionState() >= Connection.STATE_CLOSED) {
String[] args = { "" + tid, TransactionState.toString(ts.getState()), session.getConnectionUID().toString() };
logger.log(Logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_CONN_CLEANUP_KEEP_TXN, args));
translist.addOrphanAck(tid, e.getSysMessageID(), storeduid, cuid);
itr.remove();
continue;
}
}
PacketReference ref = e.getReference();
if (ref == null) {
// PART
ref = DL.get(null, e.getSysMessageID());
}
if (ref != null && !ref.isLocal()) {
itr.remove();
try {
if ((ref = e.acknowledged(false)) != null) {
try {
Destination d = ref.getDestination();
d.removeRemoteMessage(ref.getSysMessageID(), RemoveReason.ACKNOWLEDGED, ref);
} finally {
ref.postAcknowledgedRemoval();
}
}
} catch (Exception ex) {
logger.logStack(session.DEBUG_CLUSTER_MSG ? Logger.WARNING : Logger.DEBUG, "Unable to clean up remote message " + e.getDebugMessage(false), ex);
}
continue;
}
// we arent in a transaction ID .. cool
// add to redeliver list
Set s = (Set) openMsgs.get(cuid);
if (s == null) {
s = new LinkedHashSet();
openMsgs.put(cuid, s);
}
if (ref != null) {
ref.removeInDelivery(storeduid);
}
s.add(e);
}
// OK .. see if we ack or cleanup
itr = openMsgs.entrySet().iterator();
Map.Entry pair = null;
while (itr.hasNext()) {
pair = (Map.Entry) itr.next();
ConsumerUID cuid = (ConsumerUID) pair.getKey();
Map parentmp = (Map) cleanupList.get(cuid);
ConsumerUID suid = (ConsumerUID) storeMap.get(cuid);
if (parentmp == null || parentmp.size() == 0) {
Set s = (Set) pair.getValue();
Iterator sitr = s.iterator();
while (sitr.hasNext()) {
ackEntry e = (ackEntry) sitr.next();
try {
PacketReference ref = e.acknowledged(false);
if (ref != null) {
try {
Destination d = ref.getDestination();
try {
if (ref.isLocal()) {
d.removeMessage(ref.getSysMessageID(), RemoveReason.ACKNOWLEDGED);
} else {
d.removeRemoteMessage(ref.getSysMessageID(), RemoveReason.ACKNOWLEDGED, ref);
}
} catch (Exception ex) {
Object[] args = { ref, this, ex.getMessage() };
logger.logStack(Logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.X_CLEANUP_MSG_CLOSE_SESSION, args), ex);
}
} finally {
ref.postAcknowledgedRemoval();
}
}
} catch (Exception ex) {
// ignore
}
}
} else {
Map mp = new LinkedHashMap();
Set msgs = null;
PartitionedStore ps = null;
Set s = (Set) openMsgs.get(cuid);
Iterator sitr = s.iterator();
while (sitr.hasNext()) {
ackEntry e = (ackEntry) sitr.next();
PacketReference ref = e.getReference();
if (ref != null) {
try {
if (!e.hasMarkConsumed()) {
ref.consumed(suid, !session.isUnsafeAck(cuid), session.isAutoAck(cuid));
}
} catch (Exception ex) {
logger.logStack(Logger.WARNING, "Unable to consume " + suid + ":" + ref, ex);
}
ps = ref.getPartitionedStore();
if (!ref.getDestinationUID().isQueue()) {
ps = new NoPersistPartitionedStoreImpl(suid);
}
msgs = (Set) mp.get(ps);
if (msgs == null) {
msgs = new LinkedHashSet();
mp.put(ps, msgs);
}
msgs.add(ref);
} else {
sitr.remove();
}
}
SubSet pl = null;
itr = mp.entrySet().iterator();
pair = null;
while (itr.hasNext()) {
pair = (Map.Entry) itr.next();
ps = (PartitionedStore) pair.getKey();
pl = (SubSet) parentmp.get(ps);
if (pl != null) {
((Prioritized) pl).addAllOrdered((Set) pair.getValue());
} else {
logger.log(logger.WARNING, "Message(s) " + mp.get(ps) + "[" + suid + ", " + cuid + "] parentlist not found on session closing");
}
}
}
}
deliveredMessages.clear();
cleanupList.clear();
storeMap.clear();
}
}
if (!session.isXATransacted()) {
Iterator itr = null;
synchronized (detachedRConsumerUIDs) {
itr = (new LinkedHashSet(detachedRConsumerUIDs)).iterator();
}
while (itr.hasNext()) {
Consumer c = Consumer.newInstance((ConsumerUID) itr.next());
try {
Globals.getClusterBroadcast().destroyConsumer(c, null, true);
} catch (Exception e) {
logger.log(Logger.WARNING, "Unable to send consumer [" + c + "] cleanup notification for closing of SessionOp[" + this + "].");
}
}
}
}
use of com.sun.messaging.jmq.util.JMQXid in project openmq by eclipse-ee4j.
the class TransactionUtil method getXID.
public static String getXID(TransactionUID tid) {
TransactionList[] tls = Globals.getDestinationList().getTransactionList(null);
TransactionList tl = tls[0];
JMQXid xid;
if (tl == null) {
return (null);
}
xid = tl.UIDToXid(tid);
if (xid == null) {
return (null);
}
return (xid.toString());
}
Aggregations