private void registerRemoteTransaction(GlobalTransaction gtx, RemoteTransaction rtx) { RemoteTransaction transaction = remoteTransactions.put(gtx, rtx); if (transaction != null) { log.remoteTxAlreadyRegistered(); throw new IllegalStateException( "A remote transaction with the given id was already registered!!!"); } log.tracef("Created and registered remote transaction %s", rtx); if (rtx.getTopologyId() < minTxTopologyId) { log.tracef( "Changing minimum topology ID from %d to %d", minTxTopologyId, rtx.getTopologyId()); minTxTopologyId = rtx.getTopologyId(); } }
public void cleanupStaleTransactions(CacheTopology cacheTopology) { int topologyId = cacheTopology.getTopologyId(); List<Address> members = cacheTopology.getMembers(); // We only care about transactions originated before this topology update if (getMinTopologyId() >= topologyId) return; log.tracef( "Checking for transactions originated on leavers. Current members are %s, remote transactions: %d", members, remoteTransactions.size()); Set<GlobalTransaction> toKill = new HashSet<GlobalTransaction>(); for (Map.Entry<GlobalTransaction, RemoteTransaction> e : remoteTransactions.entrySet()) { GlobalTransaction gt = e.getKey(); RemoteTransaction remoteTx = e.getValue(); log.tracef("Checking transaction %s", gt); // The topology id check is needed for joiners if (remoteTx.getTopologyId() < topologyId && !members.contains(gt.getAddress())) { toKill.add(gt); } } if (toKill.isEmpty()) { log.tracef("No global transactions pertain to originator(s) who have left the cluster."); } else { log.tracef("%s global transactions pertain to leavers and need to be killed", toKill.size()); } for (GlobalTransaction gtx : toKill) { log.tracef("Killing remote transaction originating on leaver %s", gtx); RollbackCommand rc = new RollbackCommand(cacheName, gtx); rc.init(invoker, icc, TransactionTable.this); try { rc.perform(null); log.tracef("Rollback of transaction %s complete.", gtx); } catch (Throwable e) { log.unableToRollbackGlobalTx(gtx, e); } } log.tracef( "Completed cleaning transactions originating on leavers. Remote transactions remaining: %d", remoteTransactions.size()); }
private RemoteTransaction getOrCreateRemoteTransaction( GlobalTransaction globalTx, WriteCommand[] modifications, int topologyId) { RemoteTransaction remoteTransaction = remoteTransactions.get(globalTx); if (remoteTransaction != null) return remoteTransaction; remoteTransaction = modifications == null ? txFactory.newRemoteTransaction(globalTx, topologyId) : txFactory.newRemoteTransaction(modifications, globalTx, topologyId); RemoteTransaction existing = remoteTransactions.putIfAbsent(globalTx, remoteTransaction); if (existing != null) { log.tracef("Remote transaction already registered: %s", existing); return existing; } else { log.tracef("Created and registered remote transaction %s", remoteTransaction); if (remoteTransaction.getTopologyId() < minTxTopologyId) { log.tracef( "Changing minimum topology ID from %d to %d", minTxTopologyId, remoteTransaction.getTopologyId()); minTxTopologyId = remoteTransaction.getTopologyId(); } return remoteTransaction; } }
public Set<Object> getLockedKeysForRemoteTransaction(GlobalTransaction gtx) { RemoteTransaction transaction = remoteTransactions.get(gtx); if (transaction == null) return InfinispanCollections.emptySet(); return transaction.getLockedKeys(); }