use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.
the class GridCacheAdapter method syncOp.
/**
* @param op Cache operation.
* @param <T> Return type.
* @return Operation result.
* @throws IgniteCheckedException If operation failed.
*/
@SuppressWarnings({ "TypeMayBeWeakened", "ErrorNotRethrown", "AssignmentToCatchBlockParameter" })
@Nullable
private <T> T syncOp(SyncOp<T> op) throws IgniteCheckedException {
checkJta();
awaitLastFut();
GridNearTxLocal tx = ctx.tm().threadLocalTx(ctx);
if (tx == null || tx.implicit()) {
TransactionConfiguration tCfg = CU.transactionConfiguration(ctx, ctx.kernalContext().config());
CacheOperationContext opCtx = ctx.operationContextPerCall();
int retries = opCtx != null && opCtx.noRetries() ? 1 : MAX_RETRIES;
for (int i = 0; i < retries; i++) {
tx = ctx.tm().newTx(true, op.single(), ctx.systemTx() ? ctx : null, OPTIMISTIC, READ_COMMITTED, tCfg.getDefaultTxTimeout(), !ctx.skipStore(), 0);
assert tx != null;
try {
T t = op.op(tx);
assert tx.done() : "Transaction is not done: " + tx;
return t;
} catch (IgniteInterruptedCheckedException | IgniteTxHeuristicCheckedException | NodeStoppingException e) {
throw e;
} catch (IgniteCheckedException e) {
if (!(e instanceof IgniteTxRollbackCheckedException)) {
try {
tx.rollback();
e = new IgniteTxRollbackCheckedException("Transaction has been rolled back: " + tx.xid(), e);
} catch (IgniteCheckedException | AssertionError | RuntimeException e1) {
U.error(log, "Failed to rollback transaction (cache may contain stale locks): " + tx, e1);
if (e != e1)
e.addSuppressed(e1);
}
}
if (X.hasCause(e, ClusterTopologyCheckedException.class) && i != retries - 1) {
ClusterTopologyCheckedException topErr = e.getCause(ClusterTopologyCheckedException.class);
if (!(topErr instanceof ClusterTopologyServerNotFoundException)) {
AffinityTopologyVersion topVer = tx.topologyVersion();
assert topVer != null && topVer.topologyVersion() > 0 : tx;
ctx.affinity().affinityReadyFuture(topVer.topologyVersion() + 1).get();
continue;
}
}
throw e;
} finally {
ctx.tm().resetContext();
if (ctx.isNear())
ctx.near().dht().context().tm().resetContext();
}
}
// Should not happen.
throw new IgniteCheckedException("Failed to perform cache operation (maximum number of retries exceeded).");
} else
return op.op(tx);
}
use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.
the class HibernateReadWriteAccessStrategy method unlock.
/**
* @param ctx Transaction context.
* @param key Key.
*/
private void unlock(TxContext ctx, Object key) {
if (ctx.unlocked(key)) {
// Finish transaction if last key is unlocked.
txCtx.remove();
GridNearTxLocal tx = cache.tx();
assert tx != null;
try {
tx.proxy().commit();
} finally {
tx.proxy().close();
}
assert cache.tx() == null;
}
}
use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.
the class GridCacheLockImpl method initializeReentrantLock.
/**
* @throws IgniteCheckedException If operation failed.
*/
private void initializeReentrantLock() throws IgniteCheckedException {
if (initGuard.compareAndSet(false, true)) {
try {
sync = retryTopologySafe(new Callable<Sync>() {
@Override
public Sync call() throws Exception {
try (GridNearTxLocal tx = CU.txStartInternal(ctx, cacheView, PESSIMISTIC, REPEATABLE_READ)) {
GridCacheLockState val = cacheView.get(key);
if (val == null) {
if (log.isDebugEnabled())
log.debug("Failed to find reentrant lock with given name: " + name);
return null;
}
tx.rollback();
return new Sync(val);
}
}
});
if (log.isDebugEnabled())
log.debug("Initialized internal sync structure: " + sync);
} finally {
initLatch.countDown();
}
} else {
U.await(initLatch);
if (sync == null)
throw new IgniteCheckedException("Internal reentrant lock has not been properly initialized.");
}
}
use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.
the class IgfsMetaManager method lock.
/**
* Lock the file explicitly outside of transaction.
*
* @param fileId File ID to lock.
* @param del If file is being locked for delete.
* @return Locked file info or {@code null} if file cannot be locked or doesn't exist.
* @throws IgniteCheckedException If the file with such id does not exist, or on another failure.
*/
@Nullable
public IgfsEntryInfo lock(IgniteUuid fileId, boolean del) throws IgniteCheckedException {
if (busyLock.enterBusy()) {
try {
validTxState(false);
assert fileId != null;
try (GridNearTxLocal tx = startTx()) {
// Lock file ID for this transaction.
IgfsEntryInfo oldInfo = info(fileId);
if (oldInfo == null)
return null;
if (oldInfo.lockId() != null)
// The file is already locked, we cannot lock it.
return null;
IgfsEntryInfo newInfo = invokeLock(fileId, del);
tx.commit();
return newInfo;
} catch (GridClosureException e) {
throw U.cast(e);
}
} finally {
busyLock.leaveBusy();
}
} else
throw new IllegalStateException("Failed to obtain lock because Grid is stopping: " + fileId);
}
use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.
the class IgfsMetaManager method format.
/**
* Deletes (moves to TRASH) all elements under the root folder.
*
* @return The new Id if the artificially created folder containing all former root
* elements moved to TRASH folder.
* @throws IgniteCheckedException On error.
*/
@SuppressWarnings("RedundantCast")
IgniteUuid format() throws IgniteCheckedException {
if (busyLock.enterBusy()) {
try {
validTxState(false);
IgniteUuid trashId = IgfsUtils.randomTrashId();
try (GridNearTxLocal tx = startTx()) {
// NB: We may lock root because its id is less than any other id:
final IgfsEntryInfo rootInfo = lockIds(IgfsUtils.ROOT_ID, trashId).get(IgfsUtils.ROOT_ID);
assert rootInfo != null;
Map<String, IgfsListingEntry> rootListingMap = rootInfo.listing();
assert rootListingMap != null;
if (rootListingMap.isEmpty())
// Root is empty, nothing to do.
return null;
// Construct new info and move locked entries from root to it.
Map<String, IgfsListingEntry> transferListing = new HashMap<>(rootListingMap);
IgfsEntryInfo newInfo = IgfsUtils.createDirectory(IgniteUuid.randomUuid(), transferListing, (Map<String, String>) null);
createNewEntry(newInfo, trashId, newInfo.id().toString());
// Remove listing entries from root.
// Note that root directory properties and other attributes are preserved:
id2InfoPrj.put(IgfsUtils.ROOT_ID, rootInfo.listing(null));
tx.commit();
signalDeleteWorker();
return newInfo.id();
}
} finally {
busyLock.leaveBusy();
}
} else
throw new IllegalStateException("Failed to perform format because Grid is stopping.");
}
Aggregations