use of com.sun.messaging.jmq.util.JMQXid in project openmq by eclipse-ee4j.
the class XAResourceImpl method prepare.
/**
* 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.
*/
private int prepare(Xid foreignXid, boolean onePhase, boolean insyncstate) throws XAException {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine(_lgrPrefix + "XAResourceImpl (" + this.hashCode() + ") Prepare " + printXid(foreignXid));
}
// JMS does not do RDONLY transactions - right?
int result = XA_OK;
// convert to jmq xid
JMQXid jmqXid = new JMQXid(foreignXid);
if (Debug.debug) {
Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:prepare:txid=\n" + jmqXid.toString());
}
try {
// HACC
if (this._session.isRollbackOnly) {
Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:prepare:forcing Rollback due to:" + this._session.rollbackCause.getMessage());
// Debug.printStackTrace(this._session.rollbackCause);
if (connectionConsumer != null && this._session.rollbackCause instanceof RemoteAcknowledgeException) {
throw this._session.rollbackCause;
}
XAException xae = new XAException(XAException.XAER_RMFAIL);
xae.initCause(this._session.rollbackCause);
throw xae;
}
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) {
// Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:prepare:using 0 as txnID");
_connection.getProtocolHandler().prepare(0L, jmqXid, onePhase);
} else {
// Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:prepare:using real txnID");
// Setup protocol Handler
_transaction.setProtocolHandler(_connection.getProtocolHandler());
// Perform XA prepare
if (onePhase) {
_connection.getProtocolHandler().prepare(0L, jmqXid, onePhase);
} else {
_transaction.prepareXATransaction(jmqXid);
}
}
// _connection.closeConnection();
// Bug6664278 - must synced
_connection.closeConnectionFromRA();
} catch (Throwable jmse) {
// Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:prepareXAException");
Debug.printStackTrace(jmse);
if (jmse instanceof XAException) {
throw (XAException) jmse;
}
XAException xae = new XAException(XAException.XAER_RMFAIL);
xae.initCause(jmse);
if (jmse instanceof RemoteAcknowledgeException) {
if (connectionConsumer != null) {
ConnectionConsumerImpl cc = connectionConsumer;
if (!cc.canRecreate()) {
throw xae;
}
try {
this.rollback(foreignXid);
xae = new XAException(XAException.XA_RBROLLBACK);
xae.initCause(jmse);
lastInternalRBCache.put(this, jmqXid);
lastInternalRB = true;
} catch (Throwable t) {
SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on rollback transaction " + jmqXid + " after prepared failed with remote exception", t);
} finally {
cc.notifyRecreation((RemoteAcknowledgeException) jmse);
}
} else if (_session.isRemoteException((RemoteAcknowledgeException) jmse)) {
try {
this.rollback(foreignXid);
xae = new XAException(XAException.XA_RBROLLBACK);
xae.initCause(jmse);
lastInternalRBCache.put(this, jmqXid);
lastInternalRB = true;
} catch (Throwable t) {
SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on rollback transaction " + jmqXid + " after prepare failed with remote exception", t);
}
if (!insyncstate) {
try {
_session.setInSyncState();
} catch (Throwable t) {
SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on setting sync state after prepare " + jmqXid + " failed with remote exception", t);
throw xae;
}
}
try {
_session.recreateConsumers(true);
} catch (Throwable t) {
SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on recreating consumers after prepare " + jmqXid + " failed with remote exception", t);
throw xae;
} finally {
if (!insyncstate) {
_session.releaseInSyncState();
}
}
}
} else if (jmse instanceof TransactionPrepareStateFAILEDException) {
if (onePhase) {
if (_transaction == null || _session.isClosed || connectionConsumer != null) {
try {
_connection.getProtocolHandler().rollback(0L, jmqXid, connectionConsumer != null);
xae = new XAException(XAException.XA_RBROLLBACK);
xae.initCause(jmse);
lastInternalRBCache.put(this, jmqXid);
lastInternalRB = true;
} catch (Throwable t) {
SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on rollback after TransactionPrepareStateFAILEDException " + jmqXid, t);
throw xae;
}
} else {
if (!insyncstate) {
try {
_session.setInSyncState();
} catch (Throwable t) {
SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on setting sync state on TransactionPrepareStateFAILEDException " + jmqXid, t);
throw xae;
}
}
try {
_session.rollbackAfterReceiveCommit(jmqXid);
xae = new XAException(XAException.XA_RBROLLBACK);
xae.initCause(jmse);
lastInternalRBCache.put(this, jmqXid);
lastInternalRB = true;
} catch (Throwable t) {
SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on rollback after TransactionPrepareStateFAILEDException " + jmqXid, t);
throw xae;
} finally {
if (!insyncstate) {
_session.releaseInSyncState();
}
}
}
} else {
xae = new XAException(XAException.XAER_RMERR);
xae.initCause(jmse);
}
}
throw xae;
}
// update the resource state
resourceState = PREPARED;
return result;
}
use of com.sun.messaging.jmq.util.JMQXid in project openmq by eclipse-ee4j.
the class XAResourceImpl method prepare.
/**
* two-phase commit prepare for HA.
*/
@Override
public synchronized int prepare(Xid foreignXid) throws XAException {
// result code
int result = XA_OK;
// this.twoPhasePrepared = false;
JMQXid jmqXid = null;
if (_connection.isConnectedToHABroker) {
jmqXid = new JMQXid(foreignXid);
}
try {
// two phase commit
this.prepare(foreignXid, false, false);
} catch (XAException xae) {
if (_connection.isConnectedToHABroker) {
checkPrepareStatus(xae, jmqXid);
} else {
// non HA -- propagate exception
throw xae;
}
}
if (isXATracking()) {
xaTable.put(jmqXid, XA_PREPARE);
}
return result;
}
use of com.sun.messaging.jmq.util.JMQXid in project openmq by eclipse-ee4j.
the class XAResourceImpl method start.
/**
* Starts work on behalf of a transaction branch specified in <code>foreignXid</code>.
*
* 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
* <code>foreignXid</code>.
*
* If neither TMJOIN nor TMRESUME is specified and the transaction specified by <code>foreignXid</code> 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.
*/
@Override
public void start(Xid foreignXid, int flags) throws XAException {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine(_lgrPrefix + "(" + this.hashCode() + ") Start " + printXid(foreignXid) + printFlags(flags));
}
// convert to jmq xid
JMQXid jmqXid = new JMQXid(foreignXid);
if (lastInternalRB) {
lastInternalRBCache.remove(this);
lastInternalRB = false;
}
if (Debug.debug) {
Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:start:flags=" + flags + "\txid=\n" + jmqXid.toString());
}
try {
_session.switchOnXATransaction();
_transaction = _session.transaction;
_transaction.startXATransaction(flags, jmqXid);
if (!isResume(flags)) {
XAResourceMap.register(jmqXid, this, isJoin(flags));
}
currentJMQXid = jmqXid;
} catch (JMSException jmse) {
// Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:startXAException");
Debug.printStackTrace(jmse);
XAException xae = new XAException(XAException.XAER_RMFAIL);
xae.initCause(jmse);
throw xae;
}
// update the resource state
resourceState = STARTED;
}
use of com.sun.messaging.jmq.util.JMQXid in project openmq by eclipse-ee4j.
the class TransactionManagerConfig method doRollbackCommit.
public void doRollbackCommit(String transactionID, boolean rollback) throws MBeanException {
try {
long longTid = 0;
if (transactionID == null) {
throw new Exception("Null transaction ID");
}
try {
longTid = Long.parseLong(transactionID);
} catch (Exception e) {
throw new Exception("Invalid transaction ID: " + transactionID);
}
TransactionUID tid = new TransactionUID(longTid);
TransactionList[] tls = Globals.getDestinationList().getTransactionList(null);
TransactionList tl = null;
TransactionState ts = null;
for (int i = 0; i < tls.length; i++) {
tl = tls[i];
if (tl == null) {
continue;
}
ts = tl.retrieveState(tid);
if (ts == null) {
continue;
}
break;
}
if (ts == null) {
throw new Exception(rb.getString(rb.E_NO_SUCH_TRANSACTION, tid));
}
if (ts.getState() != TransactionState.PREPARED) {
throw new Exception(rb.getString(rb.E_TRANSACTION_NOT_PREPARED, tid));
}
JMQXid xid = tl.UIDToXid(tid);
if (xid == null) {
throw new Exception(rb.getString(rb.E_INTERNAL_BROKER_ERROR, "Could not find Xid for " + tid));
}
PacketRouter pr = Globals.getPacketRouter(0);
if (pr == null) {
throw new Exception(rb.getString(rb.E_INTERNAL_BROKER_ERROR, "Could not locate Packet Router"));
}
TransactionHandler thandler = (TransactionHandler) pr.getHandler(PacketType.ROLLBACK_TRANSACTION);
if (thandler == null) {
throw new Exception(rb.getString(rb.E_INTERNAL_BROKER_ERROR, "Could not locate Transaction Handler"));
}
if (rollback) {
thandler.doRollback(tl, tid, xid, null, ts, null, null, RollbackReason.ADMIN);
} else {
thandler.doCommit(tl, tid, xid, Integer.valueOf(XAResource.TMNOFLAGS), ts, null, false, null, null);
}
} catch (Exception e) {
String opName;
if (rollback) {
opName = TransactionOperations.ROLLBACK;
} else {
opName = TransactionOperations.COMMIT;
}
handleOperationException(opName, e);
}
}
Aggregations