Search in sources :

Example 1 with LocalTransaction

use of org.infinispan.transaction.impl.LocalTransaction in project infinispan by infinispan.

the class StateProviderImpl method collectTransactionsToTransfer.

private void collectTransactionsToTransfer(Address destination, List<TransactionInfo> transactionsToTransfer, Collection<? extends CacheTransaction> transactions, IntSet segments, CacheTopology cacheTopology) {
    int topologyId = cacheTopology.getTopologyId();
    Set<Address> members = new HashSet<>(cacheTopology.getMembers());
    // no need to filter out state transfer generated transactions because there should not be any such transactions running for any of the requested segments
    for (CacheTransaction tx : transactions) {
        final GlobalTransaction gtx = tx.getGlobalTransaction();
        // Also skip transactions that originates after state transfer starts.
        if (tx.getTopologyId() == topologyId || (transactionOriginatorChecker.isOriginatorMissing(gtx, members))) {
            if (log.isTraceEnabled())
                log.tracef("Skipping transaction %s as it was started in the current topology or by a leaver", tx);
            continue;
        }
        // transfer only locked keys that belong to requested segments
        Set<Object> filteredLockedKeys = new HashSet<>();
        // avoids the warning about synchronizing in a local variable.
        // and allows us to change the CacheTransaction internals without having to worry about it
        Consumer<Object> lockFilter = key -> {
            if (segments.contains(keyPartitioner.getSegment(key))) {
                filteredLockedKeys.add(key);
            }
        };
        tx.forEachLock(lockFilter);
        tx.forEachBackupLock(lockFilter);
        if (filteredLockedKeys.isEmpty()) {
            if (log.isTraceEnabled())
                log.tracef("Skipping transaction %s because the state requestor %s doesn't own any key", tx, destination);
            continue;
        }
        if (log.isTraceEnabled())
            log.tracef("Sending transaction %s to new owner %s", tx, destination);
        List<WriteCommand> txModifications = tx.getModifications();
        WriteCommand[] modifications = null;
        if (!txModifications.isEmpty()) {
            modifications = txModifications.toArray(new WriteCommand[0]);
        }
        // affected nodes set, so that the it receives the commit/rollback command. See ISPN-3389.
        if (tx instanceof LocalTransaction) {
            LocalTransaction localTx = (LocalTransaction) tx;
            localTx.locksAcquired(Collections.singleton(destination));
            if (log.isTraceEnabled())
                log.tracef("Adding affected node %s to transferred transaction %s (keys %s)", destination, gtx, filteredLockedKeys);
        }
        transactionsToTransfer.add(new TransactionInfo(gtx, tx.getTopologyId(), modifications, filteredLockedKeys));
    }
}
Also used : WriteCommand(org.infinispan.commands.write.WriteCommand) IntSets(org.infinispan.commons.util.IntSets) ComponentName(org.infinispan.factories.annotations.ComponentName) LogFactory(org.infinispan.util.logging.LogFactory) KnownComponentNames(org.infinispan.factories.KnownComponentNames) Stop(org.infinispan.factories.annotations.Stop) Scopes(org.infinispan.factories.scopes.Scopes) CompletableFutures(org.infinispan.util.concurrent.CompletableFutures) Map(java.util.Map) Scope(org.infinispan.factories.scopes.Scope) TransactionOriginatorChecker(org.infinispan.transaction.impl.TransactionOriginatorChecker) CommandsFactory(org.infinispan.commands.CommandsFactory) ConsistentHash(org.infinispan.distribution.ch.ConsistentHash) Collection(java.util.Collection) Set(java.util.Set) CacheTopology(org.infinispan.topology.CacheTopology) IntSet(org.infinispan.commons.util.IntSet) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) LocalTransaction(org.infinispan.transaction.impl.LocalTransaction) CLUSTER(org.infinispan.util.logging.Log.CLUSTER) CacheTransaction(org.infinispan.transaction.xa.CacheTransaction) ClusterCacheNotifier(org.infinispan.notifications.cachelistener.cluster.ClusterCacheNotifier) InternalCacheEntry(org.infinispan.container.entries.InternalCacheEntry) PersistenceManager(org.infinispan.persistence.manager.PersistenceManager) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList) Start(org.infinispan.factories.annotations.Start) HashSet(java.util.HashSet) Configurations(org.infinispan.configuration.cache.Configurations) KeyPartitioner(org.infinispan.distribution.ch.KeyPartitioner) Log(org.infinispan.util.logging.Log) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) MarshallableEntry(org.infinispan.persistence.spi.MarshallableEntry) Address(org.infinispan.remoting.transport.Address) InternalEntryFactory(org.infinispan.container.impl.InternalEntryFactory) Flowable(io.reactivex.rxjava3.core.Flowable) Iterator(java.util.Iterator) InternalDataContainer(org.infinispan.container.impl.InternalDataContainer) ClusterListenerReplicateCallable(org.infinispan.notifications.cachelistener.cluster.ClusterListenerReplicateCallable) Publisher(org.reactivestreams.Publisher) RpcManager(org.infinispan.remoting.rpc.RpcManager) Inject(org.infinispan.factories.annotations.Inject) Consumer(java.util.function.Consumer) GlobalTransaction(org.infinispan.transaction.xa.GlobalTransaction) Configuration(org.infinispan.configuration.cache.Configuration) Collections(java.util.Collections) TransactionTable(org.infinispan.transaction.impl.TransactionTable) DistributionManager(org.infinispan.distribution.DistributionManager) WriteCommand(org.infinispan.commands.write.WriteCommand) Address(org.infinispan.remoting.transport.Address) LocalTransaction(org.infinispan.transaction.impl.LocalTransaction) GlobalTransaction(org.infinispan.transaction.xa.GlobalTransaction) CacheTransaction(org.infinispan.transaction.xa.CacheTransaction) HashSet(java.util.HashSet)

Example 2 with LocalTransaction

use of org.infinispan.transaction.impl.LocalTransaction in project infinispan by infinispan.

the class TxDistributionInterceptor method getCommitNodes.

private Collection<Address> getCommitNodes(TxInvocationContext ctx, TopologyAffectedCommand command) {
    LocalTransaction localTx = (LocalTransaction) ctx.getCacheTransaction();
    LocalizedCacheTopology cacheTopology = checkTopologyId(command);
    Collection<Address> affectedNodes = isReplicated ? null : cacheTopology.getWriteOwners(ctx.getAffectedKeys());
    return localTx.getCommitNodes(affectedNodes, cacheTopology);
}
Also used : LocalTransaction(org.infinispan.transaction.impl.LocalTransaction) Address(org.infinispan.remoting.transport.Address) LocalizedCacheTopology(org.infinispan.distribution.LocalizedCacheTopology)

Example 3 with LocalTransaction

use of org.infinispan.transaction.impl.LocalTransaction in project infinispan by infinispan.

the class TxDistributionInterceptor method visitPrepareCommand.

@Override
public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
    if (!ctx.isOriginLocal()) {
        return invokeNext(ctx, command);
    }
    return invokeNextThenApply(ctx, command, (rCtx, rCommand, rv) -> {
        if (!shouldInvokeRemoteTxCommand((TxInvocationContext) rCtx)) {
            return rv;
        }
        TxInvocationContext<LocalTransaction> localTxCtx = (TxInvocationContext<LocalTransaction>) rCtx;
        LocalTransaction localTx = localTxCtx.getCacheTransaction();
        LocalizedCacheTopology cacheTopology = checkTopologyId(rCommand);
        Collection<Address> writeOwners = cacheTopology.getWriteOwners(localTxCtx.getAffectedKeys());
        localTx.locksAcquired(writeOwners);
        Collection<Address> recipients = isReplicated ? null : localTx.getCommitNodes(writeOwners, cacheTopology);
        CompletionStage<Object> remotePrepare = prepareOnAffectedNodes(localTxCtx, rCommand, recipients);
        return asyncValue(remotePrepare);
    });
}
Also used : LocalTransaction(org.infinispan.transaction.impl.LocalTransaction) Address(org.infinispan.remoting.transport.Address) LocalTxInvocationContext(org.infinispan.context.impl.LocalTxInvocationContext) TxInvocationContext(org.infinispan.context.impl.TxInvocationContext) LocalizedCacheTopology(org.infinispan.distribution.LocalizedCacheTopology)

Example 4 with LocalTransaction

use of org.infinispan.transaction.impl.LocalTransaction in project infinispan by infinispan.

the class PessimisticStateTransferLocksTest method checkLocksBeforeCommit.

private void checkLocksBeforeCommit(boolean backupLockOnCache1) throws Exception {
    sequencer.enter("tx:check_locks");
    assertFalse(getTransactionTable(cache(0)).getLocalTransactions().isEmpty());
    assertTrue(getTransactionTable(cache(0)).getRemoteTransactions().isEmpty());
    LocalTransaction localTx = getTransactionTable(cache(0)).getLocalTransactions().iterator().next();
    assertEquals(Collections.singleton(KEY), localTx.getLockedKeys());
    assertEquals(Collections.emptySet(), localTx.getBackupLockedKeys());
    assertTrue(getTransactionTable(cache(1)).getLocalTransactions().isEmpty());
    assertEquals(backupLockOnCache1, !getTransactionTable(cache(1)).getRemoteTransactions().isEmpty());
    assertTrue(getTransactionTable(cache(2)).getLocalTransactions().isEmpty());
    assertFalse(getTransactionTable(cache(2)).getRemoteTransactions().isEmpty());
    RemoteTransaction remoteTx = getTransactionTable(cache(2)).getRemoteTransactions().iterator().next();
    assertEquals(Collections.emptySet(), remoteTx.getLockedKeys());
    assertEquals(Collections.singleton(KEY), remoteTx.getBackupLockedKeys());
    sequencer.exit("tx:check_locks");
}
Also used : RemoteTransaction(org.infinispan.transaction.impl.RemoteTransaction) LocalTransaction(org.infinispan.transaction.impl.LocalTransaction)

Example 5 with LocalTransaction

use of org.infinispan.transaction.impl.LocalTransaction in project infinispan by infinispan.

the class StaleLocksWithCommitDuringStateTransferTest method doTestSuspect.

/**
 * Check that the transaction commit/rollback recovers if the remote node dies during the RPC
 */
private void doTestSuspect(boolean commit) throws Exception {
    MagicKey k1 = new MagicKey("k1", c1);
    MagicKey k2 = new MagicKey("k2", c2);
    tm(c1).begin();
    c1.put(k1, "v1");
    c1.put(k2, "v2");
    // We split the transaction commit in two phases by calling the TransactionCoordinator methods directly
    TransactionTable txTable = TestingUtil.extractComponent(c1, TransactionTable.class);
    TransactionCoordinator txCoordinator = TestingUtil.extractComponent(c1, TransactionCoordinator.class);
    // Execute the prepare on both nodes
    LocalTransaction localTx = txTable.getLocalTransaction(tm(c1).getTransaction());
    CompletionStages.join(txCoordinator.prepare(localTx));
    // Delay the commit on the remote node. Can't used blockNewTransactions because we don't want a StateTransferInProgressException
    AsyncInterceptorChain c2ic = c2.getAdvancedCache().getAsyncInterceptorChain();
    c2ic.addInterceptorBefore(new DelayCommandInterceptor(), StateTransferInterceptor.class);
    // Schedule the remote node to stop on another thread since the main thread will be busy with the commit call
    Thread worker = new Thread("RehasherSim,StaleLocksWithCommitDuringStateTransferTest") {

        @Override
        public void run() {
            try {
                // should be much larger than the lock acquisition timeout
                Thread.sleep(1000);
                manager(c2).stop();
            // stLock.unblockNewTransactions(1000);
            } catch (InterruptedException e) {
                log.errorf(e, "Error stopping cache");
            }
        }
    };
    worker.start();
    try {
        // finally commit or rollback the transaction
        if (commit) {
            CompletionStages.join(txCoordinator.commit(localTx, false));
        } else {
            CompletionStages.join(txCoordinator.rollback(localTx));
        }
        // make the transaction manager forget about our tx so that we don't get rollback exceptions in the log
        tm(c1).suspend();
    } finally {
        // don't leak threads
        worker.join();
    }
    // test that we don't leak locks
    assertEventuallyNotLocked(c1, k1);
    assertEventuallyNotLocked(c1, k2);
}
Also used : LocalTransaction(org.infinispan.transaction.impl.LocalTransaction) TransactionTable(org.infinispan.transaction.impl.TransactionTable) AsyncInterceptorChain(org.infinispan.interceptors.AsyncInterceptorChain) TransactionCoordinator(org.infinispan.transaction.impl.TransactionCoordinator) MagicKey(org.infinispan.distribution.MagicKey)

Aggregations

LocalTransaction (org.infinispan.transaction.impl.LocalTransaction)23 LocalTxInvocationContext (org.infinispan.context.impl.LocalTxInvocationContext)7 TransactionTable (org.infinispan.transaction.impl.TransactionTable)7 GlobalTransaction (org.infinispan.transaction.xa.GlobalTransaction)6 CompletionStage (java.util.concurrent.CompletionStage)5 TxInvocationContext (org.infinispan.context.impl.TxInvocationContext)5 Inject (org.infinispan.factories.annotations.Inject)5 RemoteTransaction (org.infinispan.transaction.impl.RemoteTransaction)5 Log (org.infinispan.util.logging.Log)5 LogFactory (org.infinispan.util.logging.LogFactory)5 Map (java.util.Map)4 Transaction (javax.transaction.Transaction)4 CommandsFactory (org.infinispan.commands.CommandsFactory)4 Start (org.infinispan.factories.annotations.Start)4 ArrayList (java.util.ArrayList)3 Collection (java.util.Collection)3 Collections (java.util.Collections)3 HashMap (java.util.HashMap)3 Iterator (java.util.Iterator)3 List (java.util.List)3