use of org.omg.CORBA.UNKNOWN in project narayana by jbosstm.
the class XAResourceRecord method commit_one_phase.
/**
* For commit_one_phase we can do whatever we want since the transaction
* outcome is whatever we want. Therefore, we do not need to save any
* additional recoverable state, such as a reference to the transaction
* coordinator, since it will not have an intentions list anyway.
*/
public void commit_one_phase() throws HeuristicHazard, org.omg.CORBA.SystemException {
if (jtaxLogger.logger.isTraceEnabled()) {
jtaxLogger.logger.trace("XAResourceRecord.commit_one_phase for " + _tranID);
}
if (_tranID == null) {
jtaxLogger.i18NLogger.warn_jtax_resources_jts_orbspecific_nulltransaction("XAResourceRecord.commit_one_phase");
throw new TRANSACTION_ROLLEDBACK();
} else {
if (_theXAResource != null) {
try {
switch(_heuristic) {
case TwoPhaseOutcome.HEURISTIC_HAZARD:
throw new org.omg.CosTransactions.HeuristicHazard();
default:
break;
}
/*
* TODO in Oracle, the end is not required. Is this
* common to other RM implementations?
*/
boolean commit = true;
XAException endRBOnly = null;
try {
endAssociation(XAResource.TMSUCCESS, TxInfo.NOT_ASSOCIATED);
} catch (XAException e1) {
switch(e1.errorCode) {
case XAException.XA_HEURHAZ:
case XAException.XA_HEURMIX:
case XAException.XA_HEURCOM:
case XAException.XA_HEURRB:
throw e1;
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:
/*
* Has been marked as rollback-only. We still
* need to call rollback.
*/
endRBOnly = e1;
commit = false;
break;
case XAException.XAER_RMERR:
case XAException.XAER_NOTA:
case XAException.XAER_PROTO:
case XAException.XAER_INVAL:
case XAException.XAER_RMFAIL:
default:
{
throw new UNKNOWN();
}
}
}
if (commit)
_theXAResource.commit(_tranID, true);
else {
_theXAResource.rollback(_tranID);
throw endRBOnly;
}
} catch (XAException e1) {
if ((e1.errorCode >= XAException.XA_RBBASE) && (e1.errorCode <= XAException.XA_RBEND)) {
throw new TRANSACTION_ROLLEDBACK();
}
switch(e1.errorCode) {
case XAException.XA_HEURHAZ:
case XAException.XA_HEURMIX:
updateState(TwoPhaseOutcome.HEURISTIC_HAZARD);
throw new org.omg.CosTransactions.HeuristicHazard();
case XAException.XA_HEURCOM:
try {
handleForget();
} catch (SystemException ignore) {
}
break;
case XAException.XA_HEURRB:
try {
handleForget();
} catch (SystemException ignore) {
}
throw new TRANSACTION_ROLLEDBACK();
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:
case XAException.XAER_RMERR:
throw new TRANSACTION_ROLLEDBACK();
case XAException.XAER_NOTA:
// RM unexpectedly lost track of the tx, outcome is uncertain
updateState(TwoPhaseOutcome.HEURISTIC_HAZARD);
throw new org.omg.CosTransactions.HeuristicHazard();
case XAException.XAER_PROTO:
case // not allowed to be thrown here by XA specification!
XAException.XA_RETRY:
// presumed abort (or we could be really paranoid and throw a heuristic)
throw new TRANSACTION_ROLLEDBACK();
case // resource manager failed, did it rollback?
XAException.XAER_INVAL:
throw new org.omg.CosTransactions.HeuristicHazard();
case // This was modified as part of JBTM-XYZ - although RMFAIL is not clear there is a rollback/commit we are flagging this to the user
XAException.XAER_RMFAIL:
throw new org.omg.CosTransactions.HeuristicHazard();
default:
// will cause log to be rewritten
_committed = true;
throw new UNKNOWN();
}
} catch (SystemException ex) {
jtaxLogger.i18NLogger.warn_jtax_resources_jts_orbspecific_cant_commit_onephase(_tranID, ex.getClass(), ex);
throw ex;
} catch (org.omg.CosTransactions.HeuristicHazard ex) {
jtaxLogger.i18NLogger.warn_jtax_resources_jts_orbspecific_cant_commit_onephase(_tranID, ex.getClass(), ex);
throw ex;
} catch (Exception e2) {
jtaxLogger.i18NLogger.warn_jtax_resources_jts_orbspecific_coperror(e2);
throw new UNKNOWN();
} finally {
removeConnection();
}
} else
throw new TRANSACTION_ROLLEDBACK();
}
}
use of org.omg.CORBA.UNKNOWN in project narayana by jbosstm.
the class TransactionImple method enlistResource.
public boolean enlistResource(XAResource xaRes, Object[] params) throws RollbackException, IllegalStateException, javax.transaction.SystemException {
if (jtaxLogger.logger.isTraceEnabled()) {
jtaxLogger.logger.trace("TransactionImple.enlistResource ( " + xaRes + " )");
}
if (xaRes == null)
throw new javax.transaction.SystemException("TransactionImple.enlistResource - " + jtaxLogger.i18NLogger.get_jtax_transaction_jts_nullparam());
int status = getStatus();
switch(status) {
case javax.transaction.Status.STATUS_MARKED_ROLLBACK:
throw new RollbackException("TransactionImple.enlistResource - " + jtaxLogger.i18NLogger.get_jtax_transaction_jts_markedrollback());
case javax.transaction.Status.STATUS_ACTIVE:
break;
default:
throw new IllegalStateException(jtaxLogger.i18NLogger.get_jtax_transaction_jts_inactivetx());
}
XAModifier theModifier = null;
if (params != null) {
if (params.length > XAMODIFIER) {
if (params[XAMODIFIER] instanceof XAModifier) {
theModifier = (XAModifier) params[XAMODIFIER];
}
}
}
try {
/*
* For each transaction we maintain a list of resources registered
* with it. Each element on this list also contains a list of
* threads which have registered this resource, and what their XID
* was for that registration.
*/
TxInfo info = null;
try {
synchronized (this) {
info = (TxInfo) _resources.get(xaRes);
if (info == null) {
/*
* Null info means it's not in the main resources list,
* but may be in the duplicates.
*/
info = (TxInfo) _duplicateResources.get(xaRes);
}
}
if (info != null) {
switch(info.getState()) {
case TxInfo.ASSOCIATION_SUSPENDED:
{
/*
* Have seen resource before, so do a resume. The
* Resource instance will still be registered with the
* transaction though.
*/
xaRes.start(info.xid(), XAResource.TMRESUME);
info.setState(TxInfo.ASSOCIATED);
synchronized (this) {
_suspendCount--;
}
// already registered resource with this
return true;
// transaction!
}
case TxInfo.ASSOCIATED:
{
return true;
}
case TxInfo.NOT_ASSOCIATED:
{
/*
* Resource was associated, but was presumably delisted.
*/
xaRes.start(info.xid(), XAResource.TMJOIN);
info.setState(TxInfo.ASSOCIATED);
return true;
}
default:
{
// block
throw new IllegalStateException("TransactionImple.enlistResource - " + jtaxLogger.i18NLogger.get_jtax_transaction_jts_illegalstate() + info.getState());
}
}
}
} catch (IllegalStateException ex) {
// we threw it in the first place
throw ex;
} catch (XAException exp) {
if (info != null)
info.setState(TxInfo.FAILED);
jtaxLogger.i18NLogger.warn_jtax_transaction_jts_xaerror("TransactionImple.enlistResource", XAHelper.printXAErrorCode(exp), exp);
return false;
}
// if (threadIsActive(xaRes))
// return true; // this thread has already registered a resource for
// this db
/*
* We definitely haven't seen this specific resource instance
* before, but that doesn't mean that we haven't seen the RM it is
* connected to.
*/
Xid xid = null;
TxInfo existingRM = isNewRM(xaRes);
if (existingRM == null) {
/*
* New RM, so create xid with new branch.
*/
boolean branchRequired = true;
synchronized (this) {
if (// first ever, so no need for
_resources.size() == 0) // branch
{
// branchRequired = false;
branchRequired = true;
}
}
xid = createXid(branchRequired, theModifier);
boolean associatedWork = false;
int retry = 20;
while (!associatedWork) {
try {
if (_xaTransactionTimeoutEnabled) {
int timeout = _theTransaction.getTimeout();
if (timeout > 0) {
try {
xaRes.setTransactionTimeout(timeout);
} catch (XAException te) {
jtaxLogger.i18NLogger.warn_jtax_transaction_jts_timeouterror("TransactionImple.enlistResource", XAHelper.printXAErrorCode(te), XAHelper.xidToString(xid), te);
}
}
}
// Pay attention now, this bit is hairy. We need to add a new XAResourceRecord
// to the transaction, which will thereafter drive its completion. However, the transaction
// core is not directly XA aware, so it's our job to start the XAResource. Problem is, if
// adding the record fails, the tx will never end the resource via the XAResourceRecord,
// so we must do so directly. start may fail due to dupl xid or other reason, and transactions
// may rollback async, for which reasons we can't call add before start.
// The xid will change on each pass of the loop, so we need to create a new record on each pass.
// The registerResource will fail in the case of multiple last resources being disallowed.
// see JBTM-362 and JBTM-363
XAResourceRecord xaResourceRecord = createRecord(xaRes, params, xid);
if (xaResourceRecord != null) {
xaRes.start(xid, XAResource.TMNOFLAGS);
try {
RecoveryCoordinator recCoord = _theTransaction.registerResource(xaResourceRecord.getResource());
xaResourceRecord.setRecoveryCoordinator(recCoord);
if (jtaxLogger.logger.isTraceEnabled()) {
jtaxLogger.logger.tracef("TransactionImple.enlistResource: " + "resource_trace: txn uid=%s XAReource=%s resource uid=%s\n", get_uid(), xaRes, xaResourceRecord.get_uid());
}
} catch (Exception e) {
// we called start on the resource, but _theTransaction did not accept it.
// we therefore have a mess which we must now clean up by ensuring the start is undone:
xaResourceRecord.rollback();
markRollbackOnly();
jtaxLogger.logger.debug("Can't set recovery coordinator for xa resource record: " + xaResourceRecord + ", " + e.getClass().getName() + ": " + e.getMessage(), e);
return false;
}
_resources.put(xaRes, new TxInfo(xid));
// dive out, no need to set associatedWork = true;
return true;
}
// if we get to here, something other than a failure of xaRes.start probably went wrong.
// so we don't loop and retry, we just give up.
markRollbackOnly();
return false;
} catch (XAException e) {
/* We get this from Oracle instead of DUPID. */
if (e.errorCode == XAException.XAER_RMERR) {
if (retry > 0)
xid = createXid(true, theModifier);
retry--;
} else if (e.errorCode == XAException.XAER_DUPID) {
if (retry > 0)
xid = createXid(true, theModifier);
retry--;
} else {
/*
* Can't do start, so set transaction to
* rollback only.
*/
jtaxLogger.i18NLogger.warn_jtax_transaction_jts_starterror("TransactionImple.enlistResource - XAResource.start", XAHelper.printXAErrorCode(e), XAHelper.xidToString(xid), e);
markRollbackOnly();
throw e;
}
if (retry < 0) {
jtaxLogger.i18NLogger.warn_jtax_transaction_jts_starterror("TransactionImple.enlistResource - XAResource.start", XAHelper.printXAErrorCode(e), XAHelper.xidToString(xid), e);
markRollbackOnly();
throw new UNKNOWN();
}
}
}
} else {
/*
* Have seen this RM before, so ignore this instance. The first
* registered RM instance will be used to drive the transaction
* completion. We add it to the duplicateResource list so we can
* delist it correctly later though.
*/
/*
* Re-create xid.
*/
xid = existingRM.xid();
try {
xaRes.start(xid, XAResource.TMJOIN);
} catch (XAException ex) {
jtaxLogger.i18NLogger.warn_jtax_transaction_jts_xaerror("TransactionImple.enlistResource - xa_start: ", XAHelper.printXAErrorCode(ex), ex);
markRollbackOnly();
throw ex;
}
/*
* Add to duplicate resources list so we can keep track of it
* (particularly if we later have to delist).
*/
_duplicateResources.put(xaRes, new TxInfo(xid));
return true;
}
return false;
} catch (Exception e) {
/*
* Some exceptional condition arose and we probably could not enlist
* the resouce. So, for safety mark the transaction as rollback
* only.
*/
jtaxLogger.i18NLogger.warn_could_not_enlist_xar(xaRes, params, e);
markRollbackOnly();
return false;
}
}
use of org.omg.CORBA.UNKNOWN in project narayana by jbosstm.
the class SynchronizationImple method after_completion.
public void after_completion(org.omg.CosTransactions.Status status) throws org.omg.CORBA.SystemException {
if (jtaxLogger.logger.isTraceEnabled()) {
jtaxLogger.logger.trace("SynchronizationImple.after_completion - Class: " + _theSynch.getClass() + " HashCode: " + _theSynch.hashCode() + " toString: " + _theSynch);
}
if (_theSynch != null) {
int s = StatusConverter.convert(status);
ClassLoader origClassLoader = this.getContextClassLoader();
try {
this.setContextClassLoader(_theClassLoader);
_theSynch.afterCompletion(s);
if (_theReference != null)
ORBManager.getPOA().shutdownObject(_thePOATie);
} catch (Exception e) {
jtaxLogger.logger.trace("SynchronizationImple.after_completion failed - toString: " + _theSynch, e);
if (_theReference != null)
ORBManager.getPOA().shutdownObject(_thePOATie);
// should not cause any affect!
throw new UNKNOWN();
} finally {
this.setContextClassLoader(origClassLoader);
}
} else
// should not cause any affect!
throw new UNKNOWN();
}
use of org.omg.CORBA.UNKNOWN in project narayana by jbosstm.
the class SynchronizationImple method before_completion.
public void before_completion() throws org.omg.CORBA.SystemException {
if (jtaxLogger.logger.isTraceEnabled()) {
jtaxLogger.logger.trace("SynchronizationImple.before_completion - Class: " + _theSynch.getClass() + " HashCode: " + _theSynch.hashCode() + " toString: " + _theSynch);
}
if (_theSynch != null) {
ClassLoader origClassLoader = this.getContextClassLoader();
try {
this.setContextClassLoader(_theClassLoader);
_theSynch.beforeCompletion();
} catch (Exception e) {
jtaxLogger.logger.trace("SynchronizationImple.before_completion failed - toString: " + _theSynch, e);
throw new UNKNOWN();
} finally {
this.setContextClassLoader(origClassLoader);
}
} else
throw new UNKNOWN();
}
use of org.omg.CORBA.UNKNOWN in project narayana by jbosstm.
the class InterpositionClientRequestInterceptorImpl method send_request.
public void send_request(ClientRequestInfo request_info) throws SystemException {
if (jtsLogger.logger.isTraceEnabled()) {
trace_request("send_request", request_info);
}
if (systemCall(request_info))
return;
final boolean otsAlwaysPropagate = InterceptorInfo.getAlwaysPropagate();
try {
if (!otsAlwaysPropagate) {
TransactionalObject ptr = TransactionalObjectHelper.narrow(request_info.target());
if (ptr == null)
throw new BAD_PARAM();
} else {
/**
* If the value is not null then we are currently in use *
*/
if (_inUse.get() != null) {
return;
} else {
/**
* Set the flag *
*/
_inUse.set(_inUse);
}
}
try {
/*
* We get back an Any, which contains a key which we must
* now use to get the actual transaction context. This saves
* use having to pack and unpack the context every time it
* changes, even if we don't then make a remote invocation.
*/
Any localData = request_info.get_slot(_localSlot);
String threadId = null;
boolean problem = false;
Any data = null;
if (localData != null && (localData.type().kind().value() != TCKind._tk_null)) {
if ((threadId = localData.extract_string()) == null)
throw new UNKNOWN(jtsLogger.i18NLogger.get_orbspecific_jacorb_interceptors_interposition_invalidparam());
} else
threadId = ThreadUtil.getThreadId();
if (threadId != null) {
ControlWrapper theControl = OTSImpleManager.systemCurrent().contextManager().current(threadId);
if (theControl != null) {
try {
Coordinator theCoordinator = theControl.get_coordinator();
PropagationContext ctx = null;
if (theCoordinator != null) {
ctx = theCoordinator.get_txcontext();
data = packPropagationContext(ctx);
theCoordinator = null;
} else
throw new Unavailable();
} catch (Unavailable ex) {
/*
* We may have to make calls during
* commit (e.g., after_completion)
* which are valid, but which will get
* Unavailable.
*/
problem = true;
}
} else
problem = true;
} else
problem = true;
if (problem) {
if (InterceptorInfo.getNeedTranContext())
throw new TRANSACTION_REQUIRED();
}
if (data != null) {
byte[] octets = _codec.encode_value(data);
ServiceContext service_context = new ServiceContext(OTSManager.serviceId, octets);
request_info.add_request_service_context(service_context, true);
}
} catch (SystemException e) {
throw e;
} catch (Exception ex) {
ex.printStackTrace();
throw new UNKNOWN(ex.toString());
} finally {
/**
* If we are set to always propagate then ensure we clear the inuse flag *
*/
if (otsAlwaysPropagate) {
_inUse.set(null);
}
}
} catch (BAD_PARAM ex) {
// narrow failed, so not a transactional object.
} catch (OBJECT_NOT_EXIST ex) {
}
}
Aggregations