boolean getLock(TXStateProxy val, TXId key) { if (!val.getLock().isHeldByCurrentThread()) { val.getLock().lock(); synchronized (this.hostedTXStates) { TXStateProxy curVal = this.hostedTXStates.get(key); // Inflight op could be received later than TXFailover operation. if (curVal == null) { if (!isHostedTxRecentlyCompleted(key)) { // Failover op removed the val // It is possible that the same operation can be executed // twice by two threads, but data is consistent. this.hostedTXStates.put(key, val); } else { // Another thread should complete the transaction logger.info("{} has already finished.", val.getTxId()); } } else { if (val != curVal) { // Failover op replaced with a new TXStateProxyImpl // Use the new one instead. val.getLock().unlock(); return false; } } } } return true; }
@Override protected boolean operateOnTx(TXId txId, ClusterDistributionManager dm) { InternalCache cache = dm.getCache(); TXManagerImpl txMgr = cache.getTXMgr(); if (logger.isDebugEnabled()) { logger.debug("JTA: Calling beforeCompletion for :{}", txId); } // Check if jta has been completed, possible due to tx failover. // No need to execute beforeCompletion if already completed. if (txMgr.isHostedTxRecentlyCompleted(txId)) { return true; } txMgr.getTXState().beforeCompletion(); return true; }
@Override protected boolean operateOnTx(TXId txId, ClusterDistributionManager dm) { InternalCache cache = dm.getCache(); if (cache == null) { throw new CacheClosedException( "A cache has not yet been created."); } TXManagerImpl txMgr = cache.getTXMgr(); if (logger.isDebugEnabled()) { logger.debug("TX: Rolling back :{}", txId); } try { if (!txMgr.isHostedTxRecentlyCompleted(txId)) { txMgr.rollback(); } } finally { txMgr.removeHostedTXState(txId); } return true; }
@Test public void testBeforeCompletionNotInvokedIfJTACompleted() throws Exception { InternalCache cache = mock(InternalCache.class); TXManagerImpl txMgr = mock(TXManagerImpl.class); ClusterDistributionManager distributionManager = mock(ClusterDistributionManager.class); TXId txId = mock(TXId.class); when(distributionManager.getCache()).thenReturn(cache); when(cache.getTXMgr()).thenReturn(txMgr); when(txMgr.isHostedTxRecentlyCompleted(txId)).thenReturn(true); when(txMgr.getTXState()).thenReturn(mock(TXStateProxyImpl.class)); JtaBeforeCompletionMessage message = new JtaBeforeCompletionMessage(1, mock(InternalDistributedMember.class), mock(ReplyProcessor21.class)); message.operateOnTx(txId, distributionManager); verify(txMgr, never()).getTXState(); }
private void rollbackTransaction(TXStateProxy existingTx) { try { if (!txMgr.isHostedTxRecentlyCompleted(txid)) { txMgr.rollback(); } } finally { txMgr.unmasquerade(existingTx); } }
try { if (txMgr.isHostedTxRecentlyCompleted(txId)) { if (logger.isDebugEnabled()) { logger.debug(
assert (!txMgr.isHostedTxRecentlyCompleted(txId));
int uniqId = clientMessage.getTransactionId(); TXId txId = new TXId(client, uniqId); if (txMgr.isHostedTxRecentlyCompleted(txId)) { if (logger.isDebugEnabled()) { logger.debug("TX: found a recently rolled back tx: {}", txId);
TXManagerImpl mgr = (TXManagerImpl) cache.getCacheTransactionManager(); reply.isHostingTx = mgr.isHostedTxInProgress(txId) || mgr.isHostedTxRecentlyCompleted(txId); if (!reply.isHostingTx) {
if (mgr.isHostedTxRecentlyCompleted(txId)) { writeReply(clientMessage, serverConnection); serverConnection.setAsTrue(RESPONDED);