@Override public Entry getEntry(KeyInfo keyInfo, LocalRegion localRegion, boolean allowTombstones) { TXStateProxy tx = localRegion.cache.getTXMgr().pauseTransaction(); try { PartitionedRegion pr = (PartitionedRegion) localRegion; return pr.nonTXGetEntry(keyInfo, false, allowTombstones); } finally { localRegion.cache.getTXMgr().unpauseTransaction(tx); } }
/** * Remove the association created by {@link #masqueradeAs(TransactionMessage)} */ public void unmasquerade(TXStateProxy tx) { if (tx != null) { if (tx.isOnBehalfOfClient()) { updateLastOperationTime(tx); } try { cleanupTransactionIfNoLongerHost(tx); } finally { setTXState(null); tx.getLock().unlock(); } } }
logger.debug("TX: Committing: {}", txId); final TXStateProxy txState = txMgr.getTXState(); TXCommitMessage commitMessage = txMgr.getRecentlyCompletedMessage(txId); try { logger.debug("TX: found a previously committed transaction:{}", txId); if (txMgr.isExceptionToken(commitMessage)) { throw txMgr.getExceptionForToken(commitMessage, txId); txMgr.commit(); commitMessage = txState.getCommitMessage(); txMgr.removeHostedTXState(txId);
/** timer task for expiring the given TXStates */ public void expireDisconnectedClientTransactions(Set<TXId> txIds, boolean distribute) { // increase the client transaction timeout setting to avoid a late in-flight client operation // preventing the expiration of the client transaction. long timeout = (long) (TimeUnit.SECONDS.toMillis(getTransactionTimeToLive()) * 1.1); if (timeout <= 0) { removeHostedTXState(txIds); } synchronized (this.hostedTXStates) { Iterator<Map.Entry<TXId, TXStateProxy>> iterator = this.hostedTXStates.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<TXId, TXStateProxy> entry = iterator.next(); if (txIds.contains(entry.getKey())) { scheduleToRemoveClientTransaction(entry.getKey(), timeout); } } } if (distribute) { expireClientTransactionsOnRemoteServer(txIds); } }
@Override public void run() { txMgr.removeHostedTXState(txid); // replace with new TXState txMgr.getOrSetHostedTXState(txid, msg); } });
@Test public void clientTransactionsToBeExpiredAreRemovedAndNotDistributedIfWithNoTimeout() { doReturn(1).when(spyTxMgr).getTransactionTimeToLive(); TXId txId1 = mock(TXId.class); TXId txId2 = mock(TXId.class); TXId txId3 = mock(TXId.class); tx1 = spyTxMgr.getOrSetHostedTXState(txId1, msg); tx2 = spyTxMgr.getOrSetHostedTXState(txId2, msg); Set<TXId> txIds = spy(new HashSet<>()); txIds.add(txId1); doReturn(0).when(spyTxMgr).getTransactionTimeToLive(); when(txIds.iterator()).thenAnswer(new Answer<Iterator<TXId>>() { @Override public Iterator<TXId> answer(InvocationOnMock invocation) throws Throwable { return Arrays.asList(txId1, txId3).iterator(); } }); assertEquals(2, spyTxMgr.getHostedTXStates().size()); spyTxMgr.expireDisconnectedClientTransactions(txIds, false); verify(spyTxMgr, never()).expireClientTransactionsOnRemoteServer(eq(txIds)); verify(spyTxMgr, times(1)).removeHostedTXState(eq(txIds)); verify(spyTxMgr, times(1)).removeHostedTXState(eq(txId1)); verify(spyTxMgr, times(1)).removeHostedTXState(eq(txId3)); assertEquals(tx2, spyTxMgr.getHostedTXStates().get(txId2)); assertEquals(1, spyTxMgr.getHostedTXStates().size()); }
@Test public void getOrSetHostedTXStateAbleToSetTXStateAndGetLock() { TXStateProxy tx = txMgr.getOrSetHostedTXState(txid, msg); assertNotNull(tx); assertEquals(tx, txMgr.getHostedTXState(txid)); assertTrue(txMgr.getLock(tx, txid)); }
@Test public void clientTransactionsToBeExpiredIsScheduledToBeRemoved() { doReturn(1).when(spyTxMgr).getTransactionTimeToLive(); TXId txId1 = mock(TXId.class); TXId txId2 = mock(TXId.class); TXId txId3 = mock(TXId.class); tx1 = spyTxMgr.getOrSetHostedTXState(txId1, msg); tx2 = spyTxMgr.getOrSetHostedTXState(txId2, msg); Set<TXId> set = new HashSet<>(); set.add(txId1); set.add(txId2); spyTxMgr.expireDisconnectedClientTransactions(set, false); verify(spyTxMgr, times(1)).scheduleToRemoveClientTransaction(eq(txId1), eq(1100L)); verify(spyTxMgr, times(1)).scheduleToRemoveClientTransaction(eq(txId2), eq(1100L)); verify(spyTxMgr, never()).scheduleToRemoveClientTransaction(eq(txId3), eq(1100L)); }
tx = this.transactionManager.pauseTransaction(); this.transactionManager.close(); this.transactionManager.unpauseTransaction(tx);
@Test public void txStateCleanedUpIfRemovedFromHostedTxStatesMap() { tx1 = txMgr.getOrSetHostedTXState(txid, msg); TXStateProxyImpl txStateProxy = (TXStateProxyImpl) tx1; assertNotNull(txStateProxy); assertFalse(txStateProxy.getLocalRealDeal().isClosed()); txMgr.masqueradeAs(tx1); // during TX failover, tx can be removed from the hostedTXStates map by FindRemoteTXMessage txMgr.getHostedTXStates().remove(txid); txMgr.unmasquerade(tx1); assertTrue(txStateProxy.getLocalRealDeal().isClosed()); }
TXStateProxy txStateProxy = null; if (resetTxState) { txStateProxy = txManager.pauseTransaction(); FetchKeysMessage m = new FetchKeysMessage(recipient, r.getPRId(), p, bucketId, InterestType.REGULAR_EXPRESSION, ".*", allowTombstones); m.setTransactionDistributed(txManager.isDistributed()); } finally { if (resetTxState) { txManager.unpauseTransaction(txStateProxy);
@Override public void run() { tx1 = txMgr.getHostedTXState(txid); assertNull(tx1); tx1 = txMgr.getOrSetHostedTXState(txid, msg); assertNotNull(tx1); assertTrue(txMgr.getLock(tx1, txid)); latch.countDown(); await() .until(() -> tx1.getLock().hasQueuedThreads()); txMgr.removeHostedTXState(txid); tx2 = txMgr.getOrSetHostedTXState(txid, msg); assertNotNull(tx2); assertTrue(txMgr.getLock(tx2, txid)); tx2.getLock().unlock(); tx1.getLock().unlock(); } });
/** * Associate the remote txState with the thread processing this message. Also, we acquire a lock * on the txState, on which this thread operates. Some messages like SizeMessage should not create * a new txState. * * @return {@link TXStateProxy} the txProxy for the transactional message */ public TXStateProxy masqueradeAs(TransactionMessage msg) throws InterruptedException { if (msg.getTXUniqId() == NOTX || !msg.canParticipateInTransaction()) { return null; } TXId key = new TXId(msg.getMemberToMasqueradeAs(), msg.getTXUniqId()); TXStateProxy val = getOrSetHostedTXState(key, msg); if (val != null) { boolean success = getLock(val, key); while (!success) { val = getOrSetHostedTXState(key, msg); if (val != null) { success = getLock(val, key); } else { break; } } } if (logger.isDebugEnabled()) { logger.debug("masqueradeAs tx {} for msg {} ", val, msg); } setTXState(val); return val; }
@Test public void clientTransactionsToBeRemovedAndDistributedAreSentToRemoveServerIfWithNoTimeout() { Set<TXId> txIds = (Set<TXId>) mock(Set.class); doReturn(0).when(spyTxMgr).getTransactionTimeToLive(); when(txIds.iterator()).thenAnswer(new Answer<Iterator<TXId>>() { @Override public Iterator<TXId> answer(InvocationOnMock invocation) throws Throwable { return Arrays.asList(txid, mock(TXId.class)).iterator(); } }); spyTxMgr.expireDisconnectedClientTransactions(txIds, true); verify(spyTxMgr, times(1)).expireClientTransactionsOnRemoteServer(eq(txIds)); }
@Before public void setup() { initMocks(this); when(cache.getDistributedSystem()).thenReturn(distributedSystem); when(distributedSystem.getDistributionManager()).thenReturn(distributionManager); when(region.getCache()).thenReturn(cache); when(region.getDistributionManager()).thenReturn(distributionManager); when(txStateProxy.isInProgress()).thenReturn(true); originalTxManager = TXManagerImpl.getCurrentInstanceForTest(); // The constructor sets the new tx manager as currentInstance txManager = spy(new TXManagerImpl(mock(CachePerfStats.class), cache)); txManager.setTXState(txStateProxy); txManager.setDistributed(false); when(cache.getTxManager()).thenReturn(txManager); }
@Test public void txStateNotCleanedupIfNotRemovedFromHostedTxStatesMap() { tx1 = txMgr.getOrSetHostedTXState(txid, msg); TXStateProxyImpl txStateProxy = (TXStateProxyImpl) tx1; assertNotNull(txStateProxy); assertFalse(txStateProxy.getLocalRealDeal().isClosed()); txMgr.masqueradeAs(tx1); txMgr.unmasquerade(tx1); assertFalse(txStateProxy.getLocalRealDeal().isClosed()); }
@Test public void clientTransactionWithIdleTimeLongerThanTransactionTimeoutIsRemoved() throws Exception { when(msg.getTXOriginatorClient()).thenReturn(mock(InternalDistributedMember.class)); TXStateProxyImpl tx = spy((TXStateProxyImpl) txMgr.getOrSetHostedTXState(txid, msg)); doReturn(true).when(tx).isOverTransactionTimeoutLimit(); txMgr.scheduleToRemoveExpiredClientTransaction(txid); assertTrue(txMgr.isHostedTXStatesEmpty()); }
@Test public void clientTransactionsToBeExpiredAndDistributedAreSentToRemoveServer() { Set<TXId> txIds = mock(Set.class); spyTxMgr.expireDisconnectedClientTransactions(txIds, true); verify(spyTxMgr, times(1)).expireClientTransactionsOnRemoteServer(eq(txIds)); }
try { txProxy.setCommitOnBehalfOfRemoteStub(true); txMgr.commit(); } finally { if (txId != null) { txMgr.removeHostedTXState(txId); txMgr.setInProgress(false);