| Method from org.jboss.tm.TransactionImpl Detail: |
public void associateCurrentThread() {
threads.add(Thread.currentThread());
}
|
public void clearThreads() {
for (int i = 0; i < threads.size(); i++)
{
Thread t = (Thread)threads.get(i);
}
}
|
public void commit() throws SecurityException, SystemException, RollbackException, IllegalStateException, HeuristicRollbackException, HeuristicMixedException {
try
{
lock();
if (trace)
{
log.trace("Committing, tx=" + this +
", status=" + getStringStatus(status));
}
switch (status)
{
case Status.STATUS_PREPARING:
throw new IllegalStateException("Already started preparing.");
case Status.STATUS_PREPARED:
throw new IllegalStateException("Already prepared.");
case Status.STATUS_ROLLING_BACK:
throw new IllegalStateException("Already started rolling back.");
case Status.STATUS_ROLLEDBACK:
instanceDone();
checkHeuristics();
throw new IllegalStateException("Already rolled back.");
case Status.STATUS_COMMITTING:
throw new IllegalStateException("Already started committing.");
case Status.STATUS_COMMITTED:
instanceDone();
checkHeuristics();
throw new IllegalStateException("Already committed.");
case Status.STATUS_NO_TRANSACTION:
throw new IllegalStateException("No transaction.");
case Status.STATUS_UNKNOWN:
throw new IllegalStateException("Unknown state");
case Status.STATUS_MARKED_ROLLBACK:
doBeforeCompletion();
endResources();
rollbackResources();
doAfterCompletion();
cancelTimeout();
instanceDone();
checkHeuristics();
throw new RollbackException("Already marked for rollback");
case Status.STATUS_ACTIVE:
break;
default:
throw new IllegalStateException("Illegal status: " + status);
}
doBeforeCompletion();
if (trace)
{
log.trace("Before completion done, tx=" + this +
", status=" + getStringStatus(status));
}
endResources();
if (status == Status.STATUS_ACTIVE)
{
if (resourceCount == 0)
{
// Zero phase commit is really fast ;-)
if (trace)
{
log.trace("Zero phase commit: No resources.");
}
status = Status.STATUS_COMMITTED;
}
else if (isOneResource())
{
// One phase commit
if (trace)
{
log.trace("One phase commit: One resource.");
}
commitResources(true);
} else
{
// Two phase commit
if (trace)
{
log.trace("Two phase commit: Many resources.");
}
if (!prepareResources())
{
boolean commitDecision =
status == Status.STATUS_PREPARED &&
(heuristicCode == HEUR_NONE ||
heuristicCode == XAException.XA_HEURCOM);
// TODO: Save decision to stable storage for recovery
// after system crash.
if (commitDecision)
commitResources(false);
} else
status = Status.STATUS_COMMITTED; // all was read-only
}
}
if (status != Status.STATUS_COMMITTED)
{
rollbackResources();
doAfterCompletion();
cancelTimeout();
// save off the cause throwable as Instance done resets it to null
Throwable causedByThrowable = cause;
instanceDone();
// throw jboss rollback exception with the saved off cause
throw new JBossRollbackException("Unable to commit, tx=" +
toString() + " status=" + getStringStatus(status),
causedByThrowable);
}
cancelTimeout();
doAfterCompletion();
instanceDone();
checkHeuristics();
if (trace)
{
log.trace("Committed OK, tx=" + this);
}
} finally {
transactionLocalMap.clear();
threads.clear();
unlock();
}
}
|
boolean containsTransactionLocal(TransactionLocal tlocal) {
return transactionLocalMap.containsKey(tlocal);
}
|
static void defaultXidFactory() {
if (xidFactory == null)
{
xidFactory = new XidFactory();
} // end of if ()
}
This static code is only present for testing purposes so a
tm can be usable without a lot of setup. |
public boolean delistResource(XAResource xaRes,
int flag) throws SystemException, IllegalStateException {
if (xaRes == null)
throw new IllegalArgumentException("null xaRes");
if (flag != XAResource.TMSUCCESS &&
flag != XAResource.TMSUSPEND &&
flag != XAResource.TMFAIL)
throw new IllegalArgumentException("Bad flag: " + flag);
try
{
lock();
if (trace)
{
log.trace("delistResource(): Entered, tx=" +
toString() + " status=" + getStringStatus(status));
}
int idx = findResource(xaRes);
if (idx == -1)
throw new IllegalArgumentException("xaRes not enlisted");
switch (status)
{
case Status.STATUS_ACTIVE:
case Status.STATUS_MARKED_ROLLBACK:
break;
case Status.STATUS_PREPARING:
throw new IllegalStateException("Already started preparing.");
case Status.STATUS_ROLLING_BACK:
throw new IllegalStateException("Already started rolling back.");
case Status.STATUS_PREPARED:
throw new IllegalStateException("Already prepared.");
case Status.STATUS_COMMITTING:
throw new IllegalStateException("Already started committing.");
case Status.STATUS_COMMITTED:
throw new IllegalStateException("Already committed.");
case Status.STATUS_ROLLEDBACK:
throw new IllegalStateException("Already rolled back.");
case Status.STATUS_NO_TRANSACTION:
throw new IllegalStateException("No transaction.");
case Status.STATUS_UNKNOWN:
throw new IllegalStateException("Unknown state");
default:
throw new IllegalStateException("Illegal status: " + status);
}
try
{
if (resourceState[idx] == RS_ENDED && !resources[idx].isSameRM(xaRes)) {
// This RM always returns false on isSameRM. Further,
// the last resource has already been delisted.
log.warn("Resource already delisted. tx=" + toString());
return false;
}
endResource(idx, flag);
return true;
} catch (XAException xae)
{
logXAException(xae);
status = Status.STATUS_MARKED_ROLLBACK;
cause = xae;
return false;
}
} finally
{
unlock();
}
}
|
public void disassociateCurrentThread() {
threads.remove(Thread.currentThread());
Thread.interrupted();
}
|
public boolean enlistResource(XAResource xaRes) throws SystemException, RollbackException, IllegalStateException {
if (xaRes == null)
throw new IllegalArgumentException("null xaRes");
try
{
lock();
if (trace)
{
log.trace("enlistResource(): Entered, tx=" +
toString() + " status=" + getStringStatus(status));
}
switch (status)
{
case Status.STATUS_ACTIVE:
case Status.STATUS_PREPARING:
break;
case Status.STATUS_PREPARED:
throw new IllegalStateException("Already prepared.");
case Status.STATUS_COMMITTING:
throw new IllegalStateException("Already started committing.");
case Status.STATUS_COMMITTED:
throw new IllegalStateException("Already committed.");
case Status.STATUS_MARKED_ROLLBACK:
throw new RollbackException("Already marked for rollback");
case Status.STATUS_ROLLING_BACK:
throw new RollbackException("Already started rolling back.");
case Status.STATUS_ROLLEDBACK:
throw new RollbackException("Already rolled back.");
case Status.STATUS_NO_TRANSACTION:
throw new IllegalStateException("No transaction.");
case Status.STATUS_UNKNOWN:
throw new IllegalStateException("Unknown state");
default:
throw new IllegalStateException("Illegal status: " + status);
}
if (resourcesEnded)
throw new IllegalStateException("Too late to enlist resources");
// Add resource
try
{
int idx = findResource(xaRes);
if (idx != -1)
{
if (resourceState[idx] == RS_ENLISTED)
return false; // already enlisted
if (resourceState[idx] == RS_ENDED && !resources[idx].isSameRM(xaRes)) {
// this is a resource that returns false on all calls to
// isSameRM. Further, the last resource enlisted has
// already been delisted, so it is time to enlist it again.
idx = -1;
} else {
startResource(idx);
return true;
}
}
for (int i = 0; i < resourceCount; ++i) {
if (resourceSameRM[i] == -1 && xaRes.isSameRM(resources[i])) {
// The xaRes is new. We register the xaRes with the Xid
// that the RM has previously seen from this transaction,
// and note that it has the same RM.
startResource(addResource(xaRes, resourceXids[i], i));
return true;
}
}
// New resource and new RM: Create a new transaction branch.
startResource(addResource(xaRes, createXidBranch(), -1));
return true;
} catch (XAException xae)
{
logXAException(xae);
cause = xae;
return false;
}
} finally
{
unlock();
}
}
|
public boolean equals(Object obj) {
if (obj != null && obj instanceof TransactionImpl)
return globalId.equals(((TransactionImpl)obj).globalId);
return false;
}
|
GlobalId getGlobalId() {
return globalId;
}
Return the global id of this transaction. |
public int getStatus() throws SystemException {
if (done)
return Status.STATUS_NO_TRANSACTION;
return status;
}
|
public long getTimeLeftBeforeTimeout() {
return (start + timeoutPeriod) - System.currentTimeMillis();
}
|
Object getTransactionLocalValue(TransactionLocal tlocal) {
return transactionLocalMap.get(tlocal);
}
|
public int hashCode() {
return globalId.hashCode();
}
|
boolean isDone() {
return done;
}
Getter for property done. |
void putTransactionLocalValue(TransactionLocal tlocal,
Object value) {
transactionLocalMap.put(tlocal, value);
}
|
public void registerSynchronization(Synchronization s) throws SystemException, RollbackException, IllegalStateException {
if (s == null)
throw new IllegalArgumentException("Null synchronization");
try
{
lock();
if (trace)
{
log.trace("registerSynchronization(): Entered, " +
"tx=" + toString() +
" status=" + getStringStatus(status));
}
switch (status) {
case Status.STATUS_ACTIVE:
case Status.STATUS_PREPARING:
break;
case Status.STATUS_PREPARED:
throw new IllegalStateException("Already prepared.");
case Status.STATUS_COMMITTING:
throw new IllegalStateException("Already started committing.");
case Status.STATUS_COMMITTED:
throw new IllegalStateException("Already committed.");
case Status.STATUS_MARKED_ROLLBACK:
throw new RollbackException("Already marked for rollback");
case Status.STATUS_ROLLING_BACK:
throw new RollbackException("Already started rolling back.");
case Status.STATUS_ROLLEDBACK:
throw new RollbackException("Already rolled back.");
case Status.STATUS_NO_TRANSACTION:
throw new IllegalStateException("No transaction.");
case Status.STATUS_UNKNOWN:
throw new IllegalStateException("Unknown state");
default:
throw new IllegalStateException("Illegal status: " + status);
}
if (syncCount == syncAllocSize)
{
// expand table
syncAllocSize = 2 * syncAllocSize;
Synchronization[] sy = new Synchronization[syncAllocSize];
System.arraycopy(sync, 0, sy, 0, syncCount);
sync = sy;
}
sync[syncCount++] = s;
} finally
{
unlock();
}
}
|
public void rollback() throws SecurityException, SystemException, IllegalStateException {
try
{
lock();
if (trace)
{
log.trace("rollback(): Entered, tx=" + toString() +
" status=" + getStringStatus(status));
}
switch (status)
{
case Status.STATUS_ACTIVE:
status = Status.STATUS_MARKED_ROLLBACK;
// fall through..
case Status.STATUS_MARKED_ROLLBACK:
doBeforeCompletion();
endResources();
rollbackResources();
cancelTimeout();
doAfterCompletion();
instanceDone();
// Cannot throw heuristic exception, so we just have to
// clear the heuristics without reporting.
heuristicCode = HEUR_NONE;
return;
case Status.STATUS_PREPARING:
// Set status to avoid race with prepareResources().
status = Status.STATUS_MARKED_ROLLBACK;
return; // commit() will do rollback.
default:
throw new IllegalStateException("Cannot rollback(), " +
"tx=" + toString() +
" status=" +
getStringStatus(status));
}
} finally {
transactionLocalMap.clear();
threads.clear();
Thread.interrupted();// clear timeout that did an interrupt
unlock();
}
}
|
public void setRollbackOnly() throws SystemException, IllegalStateException {
try {
lock();
if (trace)
log.trace("setRollbackOnly(): Entered, tx=" +
toString() + " status=" + getStringStatus(status));
switch (status) {
case Status.STATUS_ACTIVE:
case Status.STATUS_PREPARING:
case Status.STATUS_PREPARED:
status = Status.STATUS_MARKED_ROLLBACK;
// fall through..
case Status.STATUS_MARKED_ROLLBACK:
case Status.STATUS_ROLLING_BACK:
return;
case Status.STATUS_COMMITTING:
throw new IllegalStateException("Already started committing.");
case Status.STATUS_COMMITTED:
throw new IllegalStateException("Already committed.");
case Status.STATUS_ROLLEDBACK:
throw new IllegalStateException("Already rolled back.");
case Status.STATUS_NO_TRANSACTION:
throw new IllegalStateException("No transaction.");
case Status.STATUS_UNKNOWN:
throw new IllegalStateException("Unknown state");
default:
throw new IllegalStateException("Illegal status: " + status);
}
} finally {
unlock();
}
}
|
public void timedOut(Timeout timeout) {
try
{
lock();
log.warn("Transaction " + toString() + " timed out." +
" status=" + getStringStatus(status));
if (this.timeout == null)
return; // Don't race with timeout cancellation.
this.timeout = null;
switch (status)
{
case Status.STATUS_ROLLEDBACK:
case Status.STATUS_COMMITTED:
case Status.STATUS_NO_TRANSACTION:
return; // Transaction done.
case Status.STATUS_ROLLING_BACK:
return; // Will be done shortly.
case Status.STATUS_COMMITTING:
// This is _very_ bad:
// We are in the second commit phase, and have decided
// to commit, but now we get a timeout and should rollback.
// So we end up with a mixed decision.
gotHeuristic(-1, XAException.XA_HEURMIX);
status = Status.STATUS_MARKED_ROLLBACK;
return; // commit will fail
case Status.STATUS_PREPARED:
// This is bad:
// We are done with the first phase, and are persistifying
// our decision. Fortunately this case is currently never
// hit, as we do not release the lock between the two phases.
case Status.STATUS_ACTIVE:
status = Status.STATUS_MARKED_ROLLBACK;
// fall through..
case Status.STATUS_MARKED_ROLLBACK:
// don't rollback for now, this messes up with the TxInterceptor.
interruptThreads();
return;
case Status.STATUS_PREPARING:
status = Status.STATUS_MARKED_ROLLBACK;
return; // commit will fail
default:
log.warn("Unknown status at timeout, tx=" + toString());
return;
}
} finally
{
unlock();
}
}
Called when our timeout expires. |
public String toString() {
return "TransactionImpl:" + xidFactory.toString(xid);
}
|