use of org.apache.ignite.internal.processors.cache.transactions.TxCounters in project ignite by apache.
the class GridDhtTxFinishFuture method onDone.
/**
* {@inheritDoc}
*/
@Override
public boolean onDone(IgniteInternalTx tx, Throwable err) {
try (TraceSurroundings ignored = MTC.support(span)) {
if (initialized() || err != null) {
Throwable e = this.err;
if (this.tx.onePhaseCommit() && (this.tx.state() == COMMITTING)) {
try {
boolean nodeStopping = X.hasCause(err, NodeStoppingException.class);
this.tx.tmFinish(err == null, nodeStopping || cctx.kernalContext().failure().nodeStopping(), false);
} catch (IgniteCheckedException finishErr) {
U.error(log, "Failed to finish tx: " + tx, e);
if (e == null)
e = finishErr;
}
}
if (commit && e == null)
e = this.tx.commitError();
Throwable finishErr = e != null ? e : err;
if (super.onDone(tx, finishErr)) {
cctx.tm().mvccFinish(this.tx);
if (finishErr == null)
finishErr = this.tx.commitError();
if (this.tx.syncMode() != PRIMARY_SYNC)
this.tx.sendFinishReply(finishErr);
if (!this.tx.txState().mvccEnabled() && !commit && shouldApplyCountersOnRollbackError(finishErr)) {
TxCounters txCounters = this.tx.txCounters(false);
if (txCounters != null) {
try {
cctx.tm().txHandler().applyPartitionsUpdatesCounters(txCounters.updateCounters(), true, true);
} catch (IgniteCheckedException e0) {
throw new IgniteException(e0);
}
}
}
// Don't forget to clean up.
cctx.mvcc().removeFuture(futId);
return true;
}
}
return false;
}
}
use of org.apache.ignite.internal.processors.cache.transactions.TxCounters in project ignite by apache.
the class GridCacheMapEntry method mvccRemove.
/**
* {@inheritDoc}
*/
@Override
public final GridCacheUpdateTxResult mvccRemove(IgniteInternalTx tx, UUID affNodeId, AffinityTopologyVersion topVer, MvccSnapshot mvccVer, boolean needHistory, boolean needOldVal, @Nullable CacheEntryPredicate filter, boolean retVal) throws IgniteCheckedException, GridCacheEntryRemovedException {
assert tx != null;
assert mvccVer != null;
final boolean valid = valid(tx.topologyVersion());
final GridCacheVersion newVer;
WALPointer logPtr = null;
lockEntry();
MvccUpdateResult res;
try {
checkObsolete();
newVer = tx.writeVersion();
assert newVer != null : "Failed to get write version for tx: " + tx;
res = cctx.offheap().mvccRemove(this, mvccVer, tx.local(), needHistory, needOldVal, filter, retVal);
assert res != null;
if (res.resultType() == ResultType.VERSION_MISMATCH)
throw serializationError();
else if (res.resultType() == ResultType.PREV_NULL)
return new GridCacheUpdateTxResult(false);
else if (res.resultType() == ResultType.FILTERED) {
GridCacheUpdateTxResult updRes = new GridCacheUpdateTxResult(false);
updRes.filtered(true);
return updRes;
} else if (res.resultType() == ResultType.LOCKED) {
unlockEntry();
MvccVersion lockVer = res.resultVersion();
GridFutureAdapter<GridCacheUpdateTxResult> resFut = new GridFutureAdapter<>();
IgniteInternalFuture<?> lockFut = cctx.kernalContext().coordinators().waitForLock(cctx, mvccVer, lockVer);
lockFut.listen(new MvccRemoveLockListener(tx, this, affNodeId, topVer, mvccVer, needHistory, resFut, needOldVal, retVal, filter));
return new GridCacheUpdateTxResult(false, resFut);
}
if (cctx.deferredDelete() && deletedUnlocked() && !detached())
deletedUnlocked(false);
if (res.resultType() == ResultType.PREV_NOT_NULL) {
TxCounters counters = tx.txCounters(true);
if (compareIgnoreOpCounter(res.resultVersion(), mvccVer) == 0) {
if (// Do not count own update removal.
res.isKeyAbsentBefore())
counters.decrementUpdateCounter(cctx.cacheId(), partition());
} else
counters.incrementUpdateCounter(cctx.cacheId(), partition());
counters.accumulateSizeDelta(cctx.cacheId(), partition(), -1);
}
if (cctx.group().persistenceEnabled() && cctx.group().walEnabled())
logPtr = logMvccUpdate(tx, null, 0, 0L, mvccVer);
update(null, 0, 0, newVer, true);
recordNodeId(affNodeId, topVer);
} finally {
if (lockedByCurrentThread()) {
unlockEntry();
cctx.evicts().touch(this);
}
}
onUpdateFinished(0L);
GridCacheUpdateTxResult updRes = valid ? new GridCacheUpdateTxResult(true, 0L, logPtr) : new GridCacheUpdateTxResult(false, logPtr);
if (retVal && (res.resultType() == ResultType.PREV_NOT_NULL || res.resultType() == ResultType.VERSION_FOUND))
updRes.prevValue(res.oldValue());
if (needOldVal && compareIgnoreOpCounter(res.resultVersion(), mvccVer) != 0 && (res.resultType() == ResultType.PREV_NOT_NULL || res.resultType() == ResultType.REMOVED_NOT_NULL))
updRes.oldValue(res.oldValue());
updRes.mvccHistory(res.history());
return updRes;
}
use of org.apache.ignite.internal.processors.cache.transactions.TxCounters in project ignite by apache.
the class GridCacheMapEntry method mvccSet.
/**
* {@inheritDoc}
*/
@Override
public final GridCacheUpdateTxResult mvccSet(IgniteInternalTx tx, UUID affNodeId, CacheObject val, EntryProcessor entryProc, Object[] invokeArgs, long ttl0, AffinityTopologyVersion topVer, MvccSnapshot mvccVer, GridCacheOperation op, boolean needHistory, boolean noCreate, boolean needOldVal, CacheEntryPredicate filter, boolean retVal, boolean keepBinary) throws IgniteCheckedException, GridCacheEntryRemovedException {
assert tx != null;
final boolean valid = valid(tx.topologyVersion());
final boolean invoke = entryProc != null;
final GridCacheVersion newVer;
WALPointer logPtr = null;
ensureFreeSpace();
lockEntry();
MvccUpdateResult res;
try {
checkObsolete();
newVer = tx.writeVersion();
assert newVer != null : "Failed to get write version for tx: " + tx;
// Determine new ttl and expire time.
long expireTime, ttl = ttl0;
if (ttl == -1L) {
ttl = ttlExtras();
expireTime = expireTimeExtras();
} else
expireTime = CU.toExpireTime(ttl);
assert ttl >= 0 : ttl;
assert expireTime >= 0 : expireTime;
// Detach value before index update.
val = cctx.kernalContext().cacheObjects().prepareForCache(val, cctx);
assert val != null || invoke;
res = cctx.offheap().mvccUpdate(this, val, newVer, expireTime, mvccVer, tx.local(), needHistory, noCreate, needOldVal, filter, retVal, keepBinary, entryProc, invokeArgs);
assert res != null;
// updating the key which just has been rebalanced.
assert res.resultType() != ResultType.VERSION_FOUND || op == CREATE && tx.local() || !tx.local();
// PREV_NOT_NULL on CREATE is possible only on primary.
assert res.resultType() != ResultType.PREV_NOT_NULL || op != CREATE || tx.local();
if (res.resultType() == ResultType.VERSION_MISMATCH)
throw serializationError();
else if (res.resultType() == ResultType.FILTERED) {
GridCacheUpdateTxResult updRes = new GridCacheUpdateTxResult(invoke);
assert !invoke || res.invokeResult() != null;
if (// No-op invoke happened.
invoke)
updRes.invokeResult(res.invokeResult());
updRes.filtered(true);
if (retVal)
updRes.prevValue(res.oldValue());
return updRes;
} else if (noCreate && !invoke && res.resultType() == ResultType.PREV_NULL)
return new GridCacheUpdateTxResult(false);
else if (res.resultType() == ResultType.LOCKED) {
unlockEntry();
MvccVersion lockVer = res.resultVersion();
GridFutureAdapter<GridCacheUpdateTxResult> resFut = new GridFutureAdapter<>();
IgniteInternalFuture<?> lockFut = cctx.kernalContext().coordinators().waitForLock(cctx, mvccVer, lockVer);
lockFut.listen(new MvccUpdateLockListener(tx, this, affNodeId, topVer, val, ttl0, mvccVer, op, needHistory, noCreate, resFut, needOldVal, filter, retVal, keepBinary, entryProc, invokeArgs));
return new GridCacheUpdateTxResult(false, resFut);
} else if (op == CREATE && tx.local() && (res.resultType() == ResultType.PREV_NOT_NULL || res.resultType() == ResultType.VERSION_FOUND))
throw new IgniteTxDuplicateKeyCheckedException("Duplicate key during INSERT [key=" + key + ']');
if (cctx.deferredDelete() && deletedUnlocked() && !detached())
deletedUnlocked(false);
if (res.resultType() == ResultType.PREV_NULL) {
TxCounters counters = tx.txCounters(true);
if (compareIgnoreOpCounter(res.resultVersion(), mvccVer) == 0) {
if (res.isKeyAbsentBefore())
counters.incrementUpdateCounter(cctx.cacheId(), partition());
} else
counters.incrementUpdateCounter(cctx.cacheId(), partition());
counters.accumulateSizeDelta(cctx.cacheId(), partition(), 1);
} else if (res.resultType() == ResultType.PREV_NOT_NULL && compareIgnoreOpCounter(res.resultVersion(), mvccVer) != 0) {
TxCounters counters = tx.txCounters(true);
counters.incrementUpdateCounter(cctx.cacheId(), partition());
} else if (res.resultType() == ResultType.REMOVED_NOT_NULL) {
TxCounters counters = tx.txCounters(true);
if (compareIgnoreOpCounter(res.resultVersion(), mvccVer) == 0) {
if (// Do not count own update removal.
res.isKeyAbsentBefore())
counters.decrementUpdateCounter(cctx.cacheId(), partition());
} else
counters.incrementUpdateCounter(cctx.cacheId(), partition());
counters.accumulateSizeDelta(cctx.cacheId(), partition(), -1);
}
if (cctx.group().persistenceEnabled() && cctx.group().walEnabled()) {
logPtr = cctx.shared().wal().log(new MvccDataRecord(new MvccDataEntry(cctx.cacheId(), key, val, res.resultType() == ResultType.PREV_NULL ? CREATE : (res.resultType() == ResultType.REMOVED_NOT_NULL) ? DELETE : UPDATE, tx.nearXidVersion(), newVer, expireTime, key.partition(), 0L, mvccVer)));
}
update(val, expireTime, ttl, newVer, true);
recordNodeId(affNodeId, topVer);
} finally {
if (lockedByCurrentThread()) {
unlockEntry();
cctx.evicts().touch(this);
}
}
onUpdateFinished(0L);
GridCacheUpdateTxResult updRes = valid ? new GridCacheUpdateTxResult(true, 0L, logPtr) : new GridCacheUpdateTxResult(false, logPtr);
if (retVal && (res.resultType() == ResultType.PREV_NOT_NULL || res.resultType() == ResultType.VERSION_FOUND))
updRes.prevValue(res.oldValue());
if (needOldVal && compareIgnoreOpCounter(res.resultVersion(), mvccVer) != 0 && (res.resultType() == ResultType.PREV_NOT_NULL || res.resultType() == ResultType.REMOVED_NOT_NULL))
updRes.oldValue(res.oldValue());
updRes.newValue(res.newValue());
if (invoke && res.resultType() != ResultType.VERSION_FOUND) {
assert res.invokeResult() != null;
updRes.invokeResult(res.invokeResult());
}
updRes.mvccHistory(res.history());
return updRes;
}
Aggregations