use of org.infinispan.util.concurrent.locks.LockManager in project infinispan by infinispan.
the class TxCompletionNotificationCommand method invokeAsync.
@Override
public CompletionStage<?> invokeAsync(ComponentRegistry componentRegistry) throws Throwable {
if (log.isTraceEnabled())
log.tracef("Processing completed transaction %s", gtx);
RemoteTransaction remoteTx = null;
RecoveryManager recoveryManager = componentRegistry.getRecoveryManager().running();
if (recoveryManager != null) {
// recovery in use
if (xid != null) {
remoteTx = (RemoteTransaction) recoveryManager.removeRecoveryInformation(xid);
} else {
remoteTx = (RemoteTransaction) recoveryManager.removeRecoveryInformation(internalId);
}
}
if (remoteTx == null && gtx != null) {
TransactionTable txTable = componentRegistry.getTransactionTableRef().running();
remoteTx = txTable.removeRemoteTransaction(gtx);
}
if (remoteTx == null)
return CompletableFutures.completedNull();
forwardCommandRemotely(componentRegistry.getStateTransferManager(), remoteTx);
LockManager lockManager = componentRegistry.getLockManager().running();
lockManager.unlockAll(remoteTx.getLockedKeys(), remoteTx.getGlobalTransaction());
return CompletableFutures.completedNull();
}
use of org.infinispan.util.concurrent.locks.LockManager in project infinispan by infinispan.
the class RollbackDuringLockAcquisitionTest method testRollbackWhileWaitingForLockDuringPut.
/*
* The "real world" conditions are:
* - Narayana timeout <= lock timeout
*
* Cause/Steps:
* - Narayana aborts a transaction which is waiting for a lock "L"
* - The RollbackCommand is sent.
* - Lock "L" is not locked by the transaction, so unlockAll(context.getLockedKeys(), context.getLockOwner());
* never changes the state from WAITING => RELEASED
* - When the lock "L" is released, the state changes from WAITING => ACQUIRED
* - No RollbackCommand/CommitCommand is followed leaving the lock "L" in ACQUIRED state forever
*/
@Test(dataProvider = "sync-tm")
public void testRollbackWhileWaitingForLockDuringPut(boolean useSynchronization, TransactionManagerLookup lookup) throws Exception {
final String cacheName = concat("local-put", lookup.getClass().getSimpleName(), useSynchronization);
final String key = concat("reaper-put", lookup.getClass().getSimpleName(), useSynchronization);
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.transaction().transactionManagerLookup(lookup).transactionMode(TransactionMode.TRANSACTIONAL).lockingMode(LockingMode.PESSIMISTIC).useSynchronization(useSynchronization).recovery().disable();
builder.locking().lockAcquisitionTimeout(TimeUnit.MINUTES.toMillis(1));
cacheManager.defineConfiguration(cacheName, builder.build());
Cache<String, String> cache = cacheManager.getCache(cacheName);
LockManager lockManager = extractLockManager(cache);
TransactionManager tm = cache.getAdvancedCache().getTransactionManager();
// simulates lock acquired by other transaction
lockManager.lock(key, "_tx_", 1, TimeUnit.SECONDS).lock();
assertLocked(cache, key);
tm.begin();
CompletableFuture<?> put = cache.putAsync(key, "value1");
GlobalTransaction gtx = extractComponent(cache, TransactionTable.class).getGlobalTransaction(tm.getTransaction());
// wait until the tx is queued in the InfinispanLock
eventually(() -> lockManager.getLock(key).containsLockOwner(gtx));
// abort the transaction, simulates the TM's reaper aborting a long running transaction
tm.rollback();
// release the lock. the "put" must not acquire the lock
lockManager.unlock(key, "_tx_");
Exceptions.expectCompletionException(InvalidTransactionException.class, put);
assertNotLocked(cache, key);
assertNoTransactions(cache);
}
use of org.infinispan.util.concurrent.locks.LockManager in project infinispan by infinispan.
the class PrepareTimeoutTest method testCommitDoesntWriteAfterRollback.
public void testCommitDoesntWriteAfterRollback() throws Exception {
// Start a tx on A: put(k, v1), owners(k) = [B (primary) and C (backup)]
// Block the prepare on B and C so that it times out
// Wait for the rollback command to be executed on B and C
// Unblock the prepare on B and C
// Check that there are no locked keys or remote transactions on B and C
StateSequencer sequencer = new StateSequencer();
sequencer.logicalThread("main", "main:start", "main:check");
sequencer.logicalThread("primary", "primary:block_prepare", "primary:after_rollback", "primary:resume_prepare", "primary:after_prepare");
sequencer.logicalThread("backup", "backup:block_prepare", "backup:after_rollback", "backup:resume_prepare", "backup:after_prepare");
sequencer.order("main:start", "primary:block_prepare", "primary:after_prepare", "main:check");
sequencer.order("main:start", "backup:block_prepare", "backup:after_prepare", "main:check");
advanceOnInterceptor(sequencer, cache(1), StateTransferInterceptor.class, matchCommand(VersionedPrepareCommand.class).matchCount(0).build()).before("primary:block_prepare", "primary:resume_prepare").after("primary:after_prepare");
advanceOnInterceptor(sequencer, cache(1), StateTransferInterceptor.class, matchCommand(RollbackCommand.class).build()).after("primary:after_rollback");
advanceOnInterceptor(sequencer, cache(2), StateTransferInterceptor.class, matchCommand(VersionedPrepareCommand.class).matchCount(0).build()).before("backup:block_prepare", "backup:resume_prepare").after("backup:after_prepare");
advanceOnInterceptor(sequencer, cache(2), StateTransferInterceptor.class, matchCommand(RollbackCommand.class).build()).after("backup:after_rollback");
assertEquals(Arrays.asList(address(1), address(2)), cacheTopology(0).getDistribution(TEST_KEY).writeOwners());
sequencer.advance("main:start");
tm(0).begin();
cache(0).put(TEST_KEY, TX1_VALUE);
try {
tm(0).commit();
fail("Exception expected during commit");
} catch (Exception e) {
// expected
}
tm(0).begin();
cache(0).put(TEST_KEY, TX2_VALUE);
GlobalTransaction gtx1 = transactionTable(0).getLocalTransaction(tm(0).getTransaction()).getGlobalTransaction();
tm(0).commit();
// Wait for the 1st tx to be removed from the completed txs table
Thread.sleep(COMPLETED_TX_TIMEOUT + 1000);
assertTrue(transactionTable(1).isTransactionCompleted(gtx1));
assertTrue(transactionTable(2).isTransactionCompleted(gtx1));
sequencer.advance("main:check");
LockManager lockManager1 = TestingUtil.extractLockManager(cache(1));
assertFalse(lockManager1.isLocked(TEST_KEY));
assertFalse(transactionTable(1).containRemoteTx(gtx1));
assertFalse(transactionTable(2).containRemoteTx(gtx1));
for (Cache<?, ?> cache : caches()) {
assertEquals(TX2_VALUE, cache.get(TEST_KEY));
}
}
use of org.infinispan.util.concurrent.locks.LockManager in project infinispan by infinispan.
the class PessimisticLockingTxClusterExtendedStatisticLogicTest method createCacheManagers.
@Override
protected void createCacheManagers() {
for (int i = 0; i < NUM_NODES; ++i) {
ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.REPL_SYNC, true);
builder.clustering().hash().numSegments(1).consistentHashFactory(new ReplicatedControlledConsistentHashFactory(0));
//
builder.locking().isolationLevel(IsolationLevel.REPEATABLE_READ).lockAcquisitionTimeout(// the timeout are triggered by the TimeService!
60000);
builder.transaction().recovery().disable();
builder.transaction().lockingMode(LockingMode.PESSIMISTIC);
// builder.versioning().enable().scheme(VersioningScheme.SIMPLE);
extendedStatisticInterceptors[i] = new ExtendedStatisticInterceptor();
builder.customInterceptors().addInterceptor().interceptor(extendedStatisticInterceptors[i]).after(TxInterceptor.class);
addClusterEnabledCacheManager(builder);
}
waitForClusterToForm();
for (int i = 0; i < NUM_NODES; ++i) {
ExtendedStatisticInterceptor interceptor = extendedStatisticInterceptors[i];
CacheStatisticManager manager = extractField(interceptor, "cacheStatisticManager");
CacheStatisticCollector collector = extractField(manager, "cacheStatisticCollector");
ConcurrentGlobalContainer globalContainer = extractField(collector, "globalContainer");
ExtendedStatisticRpcManager rpcManager = (ExtendedStatisticRpcManager) extractComponent(cache(i), RpcManager.class);
ExtendedStatisticLockManager lockManager = (ExtendedStatisticLockManager) extractLockManager(cache(i));
lockManagers[i] = lockManager;
replaceField(TEST_TIME_SERVICE, "timeService", manager, CacheStatisticManager.class);
replaceField(TEST_TIME_SERVICE, "timeService", collector, CacheStatisticCollector.class);
replaceField(TEST_TIME_SERVICE, "timeService", globalContainer, ConcurrentGlobalContainer.class);
replaceField(TEST_TIME_SERVICE, "timeService", interceptor, ExtendedStatisticInterceptor.class);
replaceField(TEST_TIME_SERVICE, "timeService", lockManager, ExtendedStatisticLockManager.class);
replaceField(TEST_TIME_SERVICE, "timeService", rpcManager, ExtendedStatisticRpcManager.class);
controlledRpcManager[i] = ControlledRpcManager.replaceRpcManager(cache(i));
transactionTrackInterceptors[i] = TransactionTrackInterceptor.injectInCache(cache(i));
if (i == 0) {
LockManager actualLockManager = lockManager.getActual();
LockContainer container = extractField(actualLockManager, "lockContainer");
TestingUtil.inject(container, new WithinThreadExecutor(), lockManagerTimeService);
}
}
}
use of org.infinispan.util.concurrent.locks.LockManager in project infinispan by infinispan.
the class BaseCacheAPIPessimisticTest method testLockedStreamBlocked.
/**
* Tests to make sure that locked stream works properly when another user has the lock for a given key
*/
public void testLockedStreamBlocked() throws InterruptedException, TimeoutException, BrokenBarrierException, ExecutionException {
for (int i = 0; i < 10; i++) {
cache.put(i, "value" + i);
}
CyclicBarrier barrier = new CyclicBarrier(2);
int key = 4;
Future<Object> putFuture = fork(() -> TestingUtil.withTx(cache.getAdvancedCache().getTransactionManager(), () -> {
Object prev = cache.put(key, "value" + key + "-new");
// Wait for main thread to get to same point
barrier.await(10, TimeUnit.SECONDS);
// Main thread lets us complete
barrier.await(10, TimeUnit.SECONDS);
return prev;
}));
// Wait until fork thread has alredy locked the key
barrier.await(10, TimeUnit.SECONDS);
LockedStream<Object, Object> stream = cache.getAdvancedCache().lockedStream();
Future<?> forEachFuture = fork(() -> stream.filter(e -> e.getKey().equals(key)).forEach((c, e) -> assertEquals("value" + key + "-new", c.put(e.getKey(), String.valueOf(e.getValue() + "-other")))));
TestingUtil.assertNotDone(forEachFuture);
// Let the tx put complete
barrier.await(10, TimeUnit.SECONDS);
forEachFuture.get(10, TimeUnit.MINUTES);
// The put should replace the value that forEach inserted
assertEquals("value" + key, putFuture.get(10, TimeUnit.SECONDS));
// The put should be last since it had to wait until lock was released on forEachWithLock
assertEquals("value" + key + "-new-other", cache.get(key));
// Make sure the locks were cleaned up properly
LockManager lockManager = cache.getAdvancedCache().getComponentRegistry().getComponent(LockManager.class);
assertEquals(0, lockManager.getNumberOfLocksHeld());
}
Aggregations