use of org.apache.ignite.transactions.TransactionState in project ignite by apache.
the class GridDistributedTxRemoteAdapter method commitRemoteTx.
/** {@inheritDoc} */
@Override
public final void commitRemoteTx() throws IgniteCheckedException {
if (optimistic())
state(PREPARED);
if (!state(COMMITTING)) {
TransactionState state = state();
// If other thread is doing commit, then no-op.
if (state == COMMITTING || state == COMMITTED)
return;
if (log.isDebugEnabled())
log.debug("Failed to set COMMITTING transaction state (will rollback): " + this);
setRollbackOnly();
if (!isSystemInvalidate())
throw new IgniteCheckedException("Invalid transaction state for commit [state=" + state + ", tx=" + this + ']');
rollbackRemoteTx();
}
commitIfLocked();
}
use of org.apache.ignite.transactions.TransactionState in project ignite by apache.
the class IgniteTxAdapter method state.
/**
*
* @param state State to set.
* @param timedOut Timeout flag.
* @return {@code True} if state changed.
*/
@SuppressWarnings({ "TooBroadScope" })
protected boolean state(TransactionState state, boolean timedOut) {
boolean valid = false;
TransactionState prev;
boolean notify = false;
synchronized (this) {
prev = this.state;
switch(state) {
case ACTIVE:
{
valid = false;
break;
}
// Active is initial state and cannot be transitioned to.
case PREPARING:
{
valid = prev == ACTIVE;
break;
}
case PREPARED:
{
valid = prev == PREPARING;
break;
}
case COMMITTING:
{
valid = prev == PREPARED;
break;
}
case UNKNOWN:
{
if (setDone())
notify = true;
valid = prev == ROLLING_BACK || prev == COMMITTING;
break;
}
case COMMITTED:
{
if (setDone())
notify = true;
valid = prev == COMMITTING;
break;
}
case ROLLED_BACK:
{
if (setDone())
notify = true;
valid = prev == ROLLING_BACK;
break;
}
case MARKED_ROLLBACK:
{
valid = prev == ACTIVE || prev == PREPARING || prev == PREPARED;
break;
}
case ROLLING_BACK:
{
valid = prev == ACTIVE || prev == MARKED_ROLLBACK || prev == PREPARING || prev == PREPARED || (prev == COMMITTING && local() && !dht());
break;
}
}
if (valid) {
this.state = state;
this.timedOut = timedOut;
if (log.isDebugEnabled())
log.debug("Changed transaction state [prev=" + prev + ", new=" + this.state + ", tx=" + this + ']');
notifyAll();
} else {
if (log.isDebugEnabled())
log.debug("Invalid transaction state transition [invalid=" + state + ", cur=" + this.state + ", tx=" + this + ']');
}
}
if (notify) {
GridFutureAdapter<IgniteInternalTx> fut = finFut;
if (fut != null)
fut.onDone(this);
}
if (valid) {
// Seal transactions maps.
if (state != ACTIVE)
seal();
}
return valid;
}
use of org.apache.ignite.transactions.TransactionState in project ignite by apache.
the class IgniteTxManager method txsPreparedOrCommitted.
/**
* @param nearVer Near version ID.
* @param txNum Number of transactions.
* @param fut Result future.
* @param processedVers Processed versions.
* @return Future for flag indicating if transactions were prepared or committed or {@code null} for success future.
*/
@Nullable
private IgniteInternalFuture<Boolean> txsPreparedOrCommitted(final GridCacheVersion nearVer, int txNum, @Nullable GridFutureAdapter<Boolean> fut, @Nullable Collection<GridCacheVersion> processedVers) {
for (final IgniteInternalTx tx : txs()) {
if (nearVer.equals(tx.nearXidVersion())) {
IgniteInternalFuture<?> prepFut = tx.currentPrepareFuture();
if (prepFut != null && !prepFut.isDone()) {
if (log.isDebugEnabled())
log.debug("Transaction is preparing (will wait): " + tx);
final GridFutureAdapter<Boolean> fut0 = fut != null ? fut : new GridFutureAdapter<Boolean>();
final int txNum0 = txNum;
final Collection<GridCacheVersion> processedVers0 = processedVers;
prepFut.listen(new CI1<IgniteInternalFuture<?>>() {
@Override
public void apply(IgniteInternalFuture<?> prepFut) {
if (log.isDebugEnabled())
log.debug("Transaction prepare future finished: " + tx);
IgniteInternalFuture<Boolean> fut = txsPreparedOrCommitted(nearVer, txNum0, fut0, processedVers0);
assert fut == fut0;
}
});
return fut0;
}
TransactionState state = tx.state();
if (state == PREPARED || state == COMMITTING || state == COMMITTED) {
if (--txNum == 0) {
if (fut != null)
fut.onDone(true);
return fut;
}
} else {
if (tx.state(MARKED_ROLLBACK) || tx.state() == UNKNOWN) {
tx.rollbackAsync();
if (log.isDebugEnabled())
log.debug("Transaction was not prepared (rolled back): " + tx);
if (fut == null)
fut = new GridFutureAdapter<>();
fut.onDone(false);
return fut;
} else {
if (tx.state() == COMMITTED) {
if (--txNum == 0) {
if (fut != null)
fut.onDone(true);
return fut;
}
} else {
if (log.isDebugEnabled())
log.debug("Transaction is not prepared: " + tx);
if (fut == null)
fut = new GridFutureAdapter<>();
fut.onDone(false);
return fut;
}
}
}
if (processedVers == null)
processedVers = new HashSet<>(txNum, 1.0f);
processedVers.add(tx.xidVersion());
}
}
// if transaction was already committed.
for (Map.Entry<GridCacheVersion, Object> e : completedVersHashMap.entrySet()) {
if (e.getValue().equals(Boolean.FALSE))
continue;
GridCacheVersion ver = e.getKey();
if (processedVers != null && processedVers.contains(ver))
continue;
if (ver instanceof CommittedVersion) {
CommittedVersion commitVer = (CommittedVersion) ver;
if (commitVer.nearVer.equals(nearVer)) {
if (--txNum == 0) {
if (fut != null)
fut.onDone(true);
return fut;
}
}
}
}
if (fut == null)
fut = new GridFutureAdapter<>();
fut.onDone(false);
return fut;
}
Aggregations