use of org.apache.ignite.transactions.TransactionState in project ignite by apache.
the class TxCommands method printTxInfoResult.
/**
* Prints result of --tx --info command to output.
*
* @param res Response.
*/
private void printTxInfoResult(Map<ClusterNode, VisorTxTaskResult> res) {
String lb = null;
Map<Integer, String> usedCaches = new HashMap<>();
Map<Integer, String> usedCacheGroups = new HashMap<>();
VisorTxInfo firstInfo = null;
TxVerboseInfo firstVerboseInfo = null;
Set<TransactionState> states = new HashSet<>();
for (Map.Entry<ClusterNode, VisorTxTaskResult> entry : res.entrySet()) {
for (VisorTxInfo info : entry.getValue().getInfos()) {
assert info.getTxVerboseInfo() != null;
if (lb == null)
lb = info.getLabel();
if (firstInfo == null) {
firstInfo = info;
firstVerboseInfo = info.getTxVerboseInfo();
}
usedCaches.putAll(info.getTxVerboseInfo().usedCaches());
usedCacheGroups.putAll(info.getTxVerboseInfo().usedCacheGroups());
states.add(info.getState());
}
}
String indent = "";
logger.info("");
logger.info(indent + "Transaction detailed info:");
printTransactionDetailedInfo(res, usedCaches, usedCacheGroups, firstInfo, firstVerboseInfo, states, indent + DOUBLE_INDENT);
}
use of org.apache.ignite.transactions.TransactionState in project ignite by apache.
the class GridDhtTxLocalAdapter method addEntry.
/**
* @param msgId Message ID.
* @param e Entry to add.
* @return Future for active transactions for the time when reader was added.
* @throws IgniteCheckedException If failed.
*/
@Nullable
public IgniteInternalFuture<Boolean> addEntry(long msgId, IgniteTxEntry e) throws IgniteCheckedException {
init();
TransactionState state = state();
assert state == PREPARING : "Invalid tx state for " + "adding entry [msgId=" + msgId + ", e=" + e + ", tx=" + this + ']';
e.unmarshal(cctx, false, cctx.deploy().globalLoader());
checkInternal(e.txKey());
GridCacheContext cacheCtx = e.context();
GridDhtCacheAdapter dhtCache = cacheCtx.isNear() ? cacheCtx.near().dht() : cacheCtx.dht();
try {
IgniteTxEntry existing = entry(e.txKey());
if (existing != null) {
// Absolutely must set operation, as default is DELETE.
existing.op(e.op());
existing.value(e.value(), e.hasWriteValue(), e.hasReadValue());
existing.entryProcessors(e.entryProcessors());
existing.ttl(e.ttl());
existing.filters(e.filters());
existing.expiry(e.expiry());
existing.conflictExpireTime(e.conflictExpireTime());
existing.conflictVersion(e.conflictVersion());
} else {
existing = e;
addActiveCache(dhtCache.context(), false);
GridDhtCacheEntry cached = dhtCache.entryExx(existing.key(), topologyVersion());
existing.cached(cached);
GridCacheVersion explicit = existing.explicitVersion();
if (explicit != null) {
GridCacheVersion dhtVer = cctx.mvcc().mappedVersion(explicit);
if (dhtVer == null)
throw new IgniteCheckedException("Failed to find dht mapping for explicit entry version: " + existing);
existing.explicitVersion(dhtVer);
}
txState.addEntry(existing);
if (log.isDebugEnabled())
log.debug("Added entry to transaction: " + existing);
}
return addReader(msgId, dhtCache.entryExx(existing.key()), existing, topologyVersion());
} catch (GridDhtInvalidPartitionException ex) {
throw new IgniteCheckedException(ex);
}
}
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();
return;
}
try {
commitIfLocked();
} catch (IgniteTxHeuristicCheckedException e) {
// Treat heuristic exception as critical.
cctx.kernalContext().failure().process(new FailureContext(FailureType.CRITICAL_ERROR, e));
throw e;
}
}
use of org.apache.ignite.transactions.TransactionState in project ignite by apache.
the class IgniteTxLocalAdapter method userRollback.
/**
* {@inheritDoc}
*/
@Override
public void userRollback(boolean clearThreadMap) throws IgniteCheckedException {
TransactionState state = state();
if (state != ROLLING_BACK && state != ROLLED_BACK) {
setRollbackOnly();
throw new IgniteCheckedException("Invalid transaction state for rollback [state=" + state + ", tx=" + this + ']');
}
if (near()) {
// transaction manager, so they will be removed from cache.
for (IgniteTxEntry e : allEntries()) evictNearEntry(e, false);
}
if (DONE_FLAG_UPD.compareAndSet(this, 0, 1)) {
cctx.tm().rollbackTx(this, clearThreadMap, skipCompletedVersions());
cctx.mvccCaching().onTxFinished(this, false);
if (!internal()) {
Collection<CacheStoreManager> stores = txState.stores(cctx);
if (stores != null && !stores.isEmpty()) {
assert isWriteToStoreFromDhtValid(stores) : "isWriteToStoreFromDht can't be different within one transaction";
boolean isWriteToStoreFromDht = F.first(stores).isWriteToStoreFromDht();
if (!stores.isEmpty() && (near() || isWriteToStoreFromDht))
sessionEnd(stores, false);
}
}
}
}
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.
*/
protected final boolean state(TransactionState state, boolean timedOut) {
boolean valid = false;
TransactionState prev;
boolean notify = false;
WALPointer ptr = null;
synchronized (this) {
prev = this.state;
switch(state) {
case ACTIVE:
{
valid = prev == SUSPENDED;
break;
}
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 || prev == SUSPENDED;
break;
}
case ROLLING_BACK:
{
valid = prev == ACTIVE || prev == MARKED_ROLLBACK || prev == PREPARING || prev == PREPARED || prev == SUSPENDED || (prev == COMMITTING && local() && !dht());
break;
}
case SUSPENDED:
{
valid = prev == ACTIVE;
break;
}
}
if (valid) {
if (timedOut)
this.timedOut = true;
this.state = state;
if (log.isDebugEnabled())
log.debug("Changed transaction state [prev=" + prev + ", new=" + this.state + ", tx=" + this + ']');
recordStateChangedEvent(state);
notifyAll();
} else {
if (log.isDebugEnabled())
log.debug("Invalid transaction state transition [invalid=" + state + ", cur=" + this.state + ", tx=" + this + ']');
}
if (valid) {
// Seal transactions maps.
if (state != ACTIVE && state != SUSPENDED)
seal();
if (state == PREPARED || state == COMMITTED || state == ROLLED_BACK) {
cctx.tm().setMvccState(this, state);
ptr = cctx.tm().logTxRecord(this);
}
}
}
if (valid) {
if (ptr != null && (state == COMMITTED || state == ROLLED_BACK))
try {
cctx.wal().flush(ptr, false);
} catch (IgniteCheckedException e) {
String msg = "Failed to fsync ptr: " + ptr;
U.error(log, msg, e);
throw new IgniteException(msg, e);
}
}
if (notify) {
GridFutureAdapter<IgniteInternalTx> fut = finFut;
if (fut != null)
fut.onDone(this);
}
return valid;
}
Aggregations