Search in sources :

Example 26 with TXStateProxy

use of org.apache.geode.internal.cache.TXStateProxy in project geode by apache.

the class TXSynchronizationCommand method cmdExecute.

/*
   * (non-Javadoc)
   * 
   * @see
   * org.apache.geode.internal.cache.tier.sockets.BaseCommand#cmdExecute(org.apache.geode.internal.
   * cache.tier.sockets.Message, org.apache.geode.internal.cache.tier.sockets.ServerConnection,
   * long)
   */
@Override
public void cmdExecute(final Message clientMessage, final ServerConnection serverConnection, long start) throws IOException, ClassNotFoundException, InterruptedException {
    serverConnection.setAsTrue(REQUIRES_RESPONSE);
    CompletionType type = CompletionType.values()[clientMessage.getPart(0).getInt()];
    /* int txIdInt = */
    // [bruce] not sure if we need to
    clientMessage.getPart(1).getInt();
    // transmit this
    final Part statusPart;
    if (type == CompletionType.AFTER_COMPLETION) {
        statusPart = clientMessage.getPart(2);
    } else {
        statusPart = null;
    }
    final TXManagerImpl txMgr = (TXManagerImpl) serverConnection.getCache().getCacheTransactionManager();
    final InternalDistributedMember member = (InternalDistributedMember) serverConnection.getProxyID().getDistributedMember();
    // get the tx state without associating it with this thread. That's done later
    final TXStateProxy txProxy = txMgr.masqueradeAs(clientMessage, member, true);
    // releases them
    if (txProxy != null) {
        final boolean isDebugEnabled = logger.isDebugEnabled();
        try {
            if (type == CompletionType.BEFORE_COMPLETION) {
                Runnable beforeCompletion = new Runnable() {

                    @SuppressWarnings("synthetic-access")
                    public void run() {
                        TXStateProxy txState = null;
                        Throwable failureException = null;
                        try {
                            txState = txMgr.masqueradeAs(clientMessage, member, false);
                            if (isDebugEnabled) {
                                logger.debug("Executing beforeCompletion() notification for transaction {}", clientMessage.getTransactionId());
                            }
                            txState.setIsJTA(true);
                            txState.beforeCompletion();
                            try {
                                writeReply(clientMessage, serverConnection);
                            } catch (IOException e) {
                                if (isDebugEnabled) {
                                    logger.debug("Problem writing reply to client", e);
                                }
                            }
                            serverConnection.setAsTrue(RESPONDED);
                        } catch (ReplyException e) {
                            failureException = e.getCause();
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        } catch (Exception e) {
                            failureException = e;
                        } finally {
                            txMgr.unmasquerade(txState);
                        }
                        if (failureException != null) {
                            try {
                                writeException(clientMessage, failureException, false, serverConnection);
                            } catch (IOException ioe) {
                                if (isDebugEnabled) {
                                    logger.debug("Problem writing reply to client", ioe);
                                }
                            }
                            serverConnection.setAsTrue(RESPONDED);
                        }
                    }
                };
                TXSynchronizationRunnable sync = new TXSynchronizationRunnable(beforeCompletion);
                txProxy.setSynchronizationRunnable(sync);
                Executor exec = InternalDistributedSystem.getConnectedInstance().getDistributionManager().getWaitingThreadPool();
                exec.execute(sync);
                sync.waitForFirstExecution();
            } else {
                Runnable afterCompletion = new Runnable() {

                    @SuppressWarnings("synthetic-access")
                    public void run() {
                        TXStateProxy txState = null;
                        try {
                            txState = txMgr.masqueradeAs(clientMessage, member, false);
                            int status = statusPart.getInt();
                            if (isDebugEnabled) {
                                logger.debug("Executing afterCompletion({}) notification for transaction {}", status, clientMessage.getTransactionId());
                            }
                            txState.setIsJTA(true);
                            txState.afterCompletion(status);
                            // GemFire commits during afterCompletion - send the commit info back to the client
                            // where it can be applied to the local cache
                            TXCommitMessage cmsg = txState.getCommitMessage();
                            try {
                                CommitCommand.writeCommitResponse(cmsg, clientMessage, serverConnection);
                                txMgr.removeHostedTXState(txState.getTxId());
                            } catch (IOException e) {
                                // not much can be done here
                                if (isDebugEnabled || (e instanceof MessageTooLargeException)) {
                                    logger.warn("Problem writing reply to client", e);
                                }
                            }
                            serverConnection.setAsTrue(RESPONDED);
                        } catch (RuntimeException e) {
                            try {
                                writeException(clientMessage, e, false, serverConnection);
                            } catch (IOException ioe) {
                                if (isDebugEnabled) {
                                    logger.debug("Problem writing reply to client", ioe);
                                }
                            }
                            serverConnection.setAsTrue(RESPONDED);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        } finally {
                            txMgr.unmasquerade(txState);
                        }
                    }
                };
                // if there was a beforeCompletion call then there will be a thread
                // sitting in the waiting pool to execute afterCompletion. Otherwise
                // we have failed-over and may need to do beforeCompletion & hope that it works
                TXSynchronizationRunnable sync = txProxy.getSynchronizationRunnable();
                if (sync != null) {
                    sync.runSecondRunnable(afterCompletion);
                } else {
                    if (statusPart.getInt() == Status.STATUS_COMMITTED) {
                        TXStateProxy txState = txMgr.masqueradeAs(clientMessage, member, false);
                        try {
                            if (isDebugEnabled) {
                                logger.debug("Executing beforeCompletion() notification for transaction {} after failover", clientMessage.getTransactionId());
                            }
                            txState.setIsJTA(true);
                            txState.beforeCompletion();
                        } finally {
                            txMgr.unmasquerade(txState);
                        }
                    }
                    afterCompletion.run();
                }
            }
        } catch (Exception e) {
            writeException(clientMessage, MessageType.EXCEPTION, e, false, serverConnection);
            serverConnection.setAsTrue(RESPONDED);
        }
        if (isDebugEnabled) {
            logger.debug("Sent tx synchronization response");
        }
    }
}
Also used : TXManagerImpl(org.apache.geode.internal.cache.TXManagerImpl) CompletionType(org.apache.geode.cache.client.internal.TXSynchronizationOp.CompletionType) IOException(java.io.IOException) ReplyException(org.apache.geode.distributed.internal.ReplyException) IOException(java.io.IOException) MessageTooLargeException(org.apache.geode.internal.cache.tier.sockets.MessageTooLargeException) ReplyException(org.apache.geode.distributed.internal.ReplyException) TXSynchronizationRunnable(org.apache.geode.internal.cache.TXSynchronizationRunnable) Executor(java.util.concurrent.Executor) InternalDistributedMember(org.apache.geode.distributed.internal.membership.InternalDistributedMember) TXStateProxy(org.apache.geode.internal.cache.TXStateProxy) Part(org.apache.geode.internal.cache.tier.sockets.Part) MessageTooLargeException(org.apache.geode.internal.cache.tier.sockets.MessageTooLargeException) TXSynchronizationRunnable(org.apache.geode.internal.cache.TXSynchronizationRunnable) TXCommitMessage(org.apache.geode.internal.cache.TXCommitMessage)

Example 27 with TXStateProxy

use of org.apache.geode.internal.cache.TXStateProxy in project geode by apache.

the class RollbackCommand method cmdExecute.

@Override
public void cmdExecute(Message clientMessage, ServerConnection serverConnection, long start) throws IOException, ClassNotFoundException, InterruptedException {
    serverConnection.setAsTrue(REQUIRES_RESPONSE);
    TXManagerImpl txMgr = (TXManagerImpl) serverConnection.getCache().getCacheTransactionManager();
    InternalDistributedMember client = (InternalDistributedMember) serverConnection.getProxyID().getDistributedMember();
    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);
            sendRollbackReply(clientMessage, serverConnection);
            txMgr.removeHostedTXState(txId);
            return;
        }
    }
    final TXStateProxy txState = txMgr.getTXState();
    try {
        if (txState != null) {
            txId = txState.getTxId();
            txMgr.rollback();
            sendRollbackReply(clientMessage, serverConnection);
        } else {
            // could not find TxState in the host server.
            // Protect against a failover command received so late,
            // and it is removed from the failoverMap due to capacity.
            sendRollbackReply(clientMessage, serverConnection);
        }
    } catch (Exception e) {
        writeException(clientMessage, e, false, serverConnection);
        serverConnection.setAsTrue(RESPONDED);
    } finally {
        if (logger.isDebugEnabled()) {
            logger.debug("TX: removing tx state for {}", txId);
        }
        if (txId != null) {
            TXStateProxy proxy = txMgr.removeHostedTXState(txId);
            if (logger.isDebugEnabled()) {
                logger.debug("TX: removed tx state proxy {}", proxy);
            }
        }
    }
}
Also used : TXManagerImpl(org.apache.geode.internal.cache.TXManagerImpl) InternalDistributedMember(org.apache.geode.distributed.internal.membership.InternalDistributedMember) TXStateProxy(org.apache.geode.internal.cache.TXStateProxy) TXId(org.apache.geode.internal.cache.TXId) IOException(java.io.IOException)

Example 28 with TXStateProxy

use of org.apache.geode.internal.cache.TXStateProxy in project geode by apache.

the class TXJUnitTest method testRepeatableRead.

@Test
public void testRepeatableRead() throws CacheException {
    final TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
    TXStateProxy tx;
    // try repeating a get and make sure it doesn't cause a conflict
    // non-tx
    this.region.put("key1", "value1");
    txMgrImpl.begin();
    assertEquals("value1", this.region.get("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    assertEquals("value1", this.region.get("key1"));
    txMgrImpl.commit();
    // try repeating a get and modify the entry and make sure it causes a conflict
    // non-tx
    this.region.put("key1", "value1");
    txMgrImpl.begin();
    assertEquals("value1", this.region.get("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    assertEquals("value1", this.region.get("key1"));
    this.region.put("key1", "value3");
    assertEquals("value3", this.region.get("key1"));
    try {
        txMgrImpl.commit();
        fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    // try repeating a getEntry and make sure it doesn't cause a conflict
    // non-tx
    this.region.put("key1", "value1");
    txMgrImpl.begin();
    this.region.getEntry("key1");
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    assertEquals("value1", this.region.get("key1"));
    txMgrImpl.commit();
    // try repeating a getEntry and modify the entry and make sure it causes a conflict
    // non-tx
    this.region.put("key1", "value1");
    txMgrImpl.begin();
    this.region.getEntry("key1");
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    this.region.put("key1", "value3");
    try {
        txMgrImpl.commit();
        fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    // try RR when entry fetched using entrySet
    // non-tx
    this.region.put("key1", "value1");
    txMgrImpl.begin();
    // bootstrap the tx, entrySet does not
    this.region.get("key1");
    this.region.entrySet(false).iterator().next();
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    assertEquals("value1", this.region.get("key1"));
    txMgrImpl.commit();
    // try RRW->CONFLICT when entry fetched using entrySet
    // non-tx
    this.region.put("key1", "value1");
    txMgrImpl.begin();
    // bootstrap the tx, entrySet does not
    this.region.get("key1");
    this.region.entrySet(false).iterator().next();
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    assertEquals("value1", this.region.get("key1"));
    this.region.put("key1", "value3");
    try {
        txMgrImpl.commit();
        fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    // try containsKey
    // non-tx
    this.region.put("key1", "value1");
    txMgrImpl.begin();
    assertEquals(true, this.region.containsKey("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.remove("key1");
    txMgrImpl.internalResume(tx);
    assertEquals(true, this.region.containsKey("key1"));
    txMgrImpl.commit();
    // non-tx
    this.region.put("key1", "value1");
    txMgrImpl.begin();
    assertEquals(true, this.region.containsKey("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.remove("key1");
    txMgrImpl.internalResume(tx);
    assertEquals(true, this.region.containsKey("key1"));
    this.region.put("key1", "value3");
    assertEquals(true, this.region.containsKey("key1"));
    try {
        txMgrImpl.commit();
        fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    // try containsValueForKey
    // non-tx
    this.region.put("key1", "value1");
    txMgrImpl.begin();
    assertEquals(true, this.region.containsValueForKey("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.remove("key1");
    txMgrImpl.internalResume(tx);
    assertEquals(true, this.region.containsValueForKey("key1"));
    txMgrImpl.commit();
    // non-tx
    this.region.put("key1", "value1");
    txMgrImpl.begin();
    assertEquals(true, this.region.containsValueForKey("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.remove("key1");
    txMgrImpl.internalResume(tx);
    assertEquals(true, this.region.containsValueForKey("key1"));
    this.region.put("key1", "value3");
    assertEquals(true, this.region.containsValueForKey("key1"));
    try {
        txMgrImpl.commit();
        fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    // now try the same things but with no entry in committed state at
    // the time of the first read
    // try repeating a get and make sure it doesn't cause a conflict
    // non-tx
    this.region.remove("key1");
    txMgrImpl.begin();
    assertEquals(null, this.region.get("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    assertEquals(null, this.region.get("key1"));
    txMgrImpl.commit();
    // try repeating a get and modify the entry and make sure it causes a conflict
    // non-tx
    this.region.remove("key1");
    txMgrImpl.begin();
    assertEquals(null, this.region.get("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    assertEquals(null, this.region.get("key1"));
    this.region.put("key1", "value3");
    assertEquals("value3", this.region.get("key1"));
    try {
        txMgrImpl.commit();
        fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    // try repeating a getEntry and make sure it doesn't cause a conflict
    // non-tx
    this.region.remove("key1");
    txMgrImpl.begin();
    assertEquals(null, this.region.getEntry("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    assertEquals(null, this.region.getEntry("key1"));
    txMgrImpl.commit();
    // try repeating a getEntry and modify the entry and make sure it causes a conflict
    // non-tx
    this.region.remove("key1");
    txMgrImpl.begin();
    assertEquals(null, this.region.getEntry("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    assertEquals(null, this.region.getEntry("key1"));
    this.region.put("key1", "value3");
    try {
        txMgrImpl.commit();
        fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    // try containsKey
    // non-tx
    this.region.remove("key1");
    txMgrImpl.begin();
    assertEquals(false, this.region.containsKey("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    assertEquals(false, this.region.containsKey("key1"));
    txMgrImpl.commit();
    // non-tx
    this.region.remove("key1");
    txMgrImpl.begin();
    assertEquals(false, this.region.containsKey("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    assertEquals(false, this.region.containsKey("key1"));
    this.region.put("key1", "value3");
    assertEquals(true, this.region.containsKey("key1"));
    try {
        txMgrImpl.commit();
        fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    // try containsValueForKey
    // non-tx
    this.region.remove("key1");
    txMgrImpl.begin();
    assertEquals(false, this.region.containsValueForKey("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    assertEquals(false, this.region.containsValueForKey("key1"));
    txMgrImpl.commit();
    // non-tx
    this.region.remove("key1");
    txMgrImpl.begin();
    assertEquals(false, this.region.containsValueForKey("key1"));
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.put("key1", "value2");
    txMgrImpl.internalResume(tx);
    assertEquals(false, this.region.containsValueForKey("key1"));
    this.region.put("key1", "value3");
    assertEquals(true, this.region.containsValueForKey("key1"));
    try {
        txMgrImpl.commit();
        fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    // try an invalidate of an already invalid entry
    // non-tx
    this.region.remove("key1");
    // non-tx
    this.region.create("key1", null);
    txMgrImpl.begin();
    this.region.get("key1");
    // should be a noop since it is already invalid
    this.region.localInvalidate("key1");
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.remove("key1");
    txMgrImpl.internalResume(tx);
    txMgrImpl.commit();
    assertEquals(false, this.region.containsKey("key1"));
    // make sure a noop invalidate is repeatable read
    // non-tx
    this.region.remove("key1");
    // non-tx
    this.region.create("key1", null);
    txMgrImpl.begin();
    // should be a noop since it is already invalid
    this.region.localInvalidate("key1");
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.remove("key1");
    txMgrImpl.internalResume(tx);
    assertEquals(true, this.region.containsKey("key1"));
    assertEquals(false, this.region.containsValueForKey("key1"));
    txMgrImpl.commit();
    assertEquals(false, this.region.containsKey("key1"));
    // make sure a destroy that throws entryNotFound is repeatable read
    // non-tx
    this.region.remove("key1");
    txMgrImpl.begin();
    try {
        this.region.localDestroy("key1");
        fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException expected) {
    }
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.create("key1", "value1");
    txMgrImpl.internalResume(tx);
    assertEquals(false, this.region.containsKey("key1"));
    txMgrImpl.commit();
    assertEquals(true, this.region.containsKey("key1"));
    // non-tx
    this.region.remove("key1");
    // make sure a create that throws entryExists is repeatable read
    // non-tx
    this.region.create("key1", "non-tx-value1");
    txMgrImpl.begin();
    try {
        this.region.create("key1", "value1");
        fail("expected EntryExistsException");
    } catch (EntryExistsException expected) {
    }
    tx = txMgrImpl.internalSuspend();
    // non-tx
    this.region.remove("key1");
    txMgrImpl.internalResume(tx);
    assertEquals(true, this.region.containsKey("key1"));
    txMgrImpl.commit();
    assertEquals(false, this.region.containsKey("key1"));
}
Also used : CommitConflictException(org.apache.geode.cache.CommitConflictException) TXManagerImpl(org.apache.geode.internal.cache.TXManagerImpl) TXStateProxy(org.apache.geode.internal.cache.TXStateProxy) EntryNotFoundException(org.apache.geode.cache.EntryNotFoundException) EntryExistsException(org.apache.geode.cache.EntryExistsException) Test(org.junit.Test) IntegrationTest(org.apache.geode.test.junit.categories.IntegrationTest)

Example 29 with TXStateProxy

use of org.apache.geode.internal.cache.TXStateProxy in project geode by apache.

the class JCALocalTransaction method begin.

@Override
public void begin() throws ResourceException {
    try {
        if (!this.initDone || this.cache.isClosed()) {
            this.init();
        }
        LogWriter logger = this.cache.getLogger();
        if (logger.fineEnabled()) {
            logger.fine("JCALocalTransaction::begin:");
        }
        TransactionManager tm = this.cache.getJTATransactionManager();
        if (this.tid != null) {
            throw new LocalTransactionException(" A transaction is already in progress");
        }
        if (tm != null && tm.getTransaction() != null) {
            if (logger.fineEnabled()) {
                logger.fine("JCAManagedConnection: JTA transaction is on");
            }
            // This is having a JTA transaction. Assuming ignore jta flag is true,
            // explicitly being a gemfire transaction.
            TXStateProxy tsp = this.gfTxMgr.getTXState();
            if (tsp == null) {
                this.gfTxMgr.begin();
                tsp = this.gfTxMgr.getTXState();
                tsp.setJCATransaction();
                this.tid = tsp.getTransactionId();
                if (logger.fineEnabled()) {
                    logger.fine("JCALocalTransaction:begun GFE transaction");
                }
            } else {
                throw new LocalTransactionException("GemFire is already associated with a transaction");
            }
        } else {
            if (logger.fineEnabled()) {
                logger.fine("JCAManagedConnection: JTA Transaction does not exist.");
            }
        }
    } catch (SystemException e) {
        throw new ResourceException(e);
    }
}
Also used : LocalTransactionException(javax.resource.spi.LocalTransactionException) SystemException(javax.transaction.SystemException) LogWriter(org.apache.geode.LogWriter) TXStateProxy(org.apache.geode.internal.cache.TXStateProxy) TransactionManager(javax.transaction.TransactionManager) ResourceException(javax.resource.ResourceException)

Example 30 with TXStateProxy

use of org.apache.geode.internal.cache.TXStateProxy in project geode by apache.

the class TXJUnitTest method testJTAEnlistment.

@Test
public void testJTAEnlistment() throws CacheException, javax.transaction.NotSupportedException, javax.transaction.RollbackException, javax.transaction.SystemException, javax.transaction.HeuristicMixedException, javax.transaction.HeuristicRollbackException {
    TransactionListener tl = new TransactionListener() {

        @Override
        public void afterCommit(TransactionEvent event) {
            ++listenerAfterCommit;
            te = event;
        }

        @Override
        public void afterFailedCommit(TransactionEvent event) {
            ++listenerAfterFailedCommit;
            te = event;
        }

        @Override
        public void afterRollback(TransactionEvent event) {
            ++listenerAfterRollback;
            te = event;
        }

        @Override
        public void close() {
            ++listenerClose;
        }
    };
    this.txMgr.addListener(tl);
    javax.transaction.UserTransaction userTx = null;
    try {
        userTx = (javax.transaction.UserTransaction) this.cache.getJNDIContext().lookup("java:/UserTransaction");
    } catch (VirtualMachineError e) {
        SystemFailure.initiateFailure(e);
        throw e;
    } catch (Throwable badDog) {
        fail("Expected to get a healthy UserTransaction!");
    }
    // Test enlistment for put
    // Test enlisted rollback
    // Test prevention of rollback/commit for enlisted transaction
    assertEquals(0, this.listenerAfterRollback);
    userTx.begin();
    this.region.put("enlistKey", "enlistVal");
    assertEquals("enlistVal", this.region.getEntry("enlistKey").getValue());
    assertNotNull(this.txMgr.getTransactionId());
    try {
        this.txMgr.rollback();
        fail("Should not allow a CacheTransactionManager.rollback call once the GF Tx is enlisted");
    } catch (VirtualMachineError e) {
        SystemFailure.initiateFailure(e);
        throw e;
    } catch (Throwable ok) {
    }
    try {
        this.txMgr.commit();
        fail("Should not allow a CacheTransactionManager.commit() call once the GF Tx is enlisted");
    } catch (VirtualMachineError e) {
        SystemFailure.initiateFailure(e);
        throw e;
    } catch (Throwable alsoOk) {
    }
    userTx.rollback();
    assertNull(this.txMgr.getTransactionId());
    assertTrue(!this.region.containsKey("enlistKey"));
    assertEquals(1, this.listenerAfterRollback);
    // Test enlistment for create
    // Test commit
    assertEquals(0, this.listenerAfterCommit);
    userTx.begin();
    this.region.create("enlistKey", "enlistVal");
    assertEquals("enlistVal", this.region.getEntry("enlistKey").getValue());
    assertNotNull(this.txMgr.getTransactionId());
    userTx.commit();
    assertNull(this.txMgr.getTransactionId());
    assertTrue(this.region.containsKey("enlistKey"));
    assertEquals("enlistVal", this.region.getEntry("enlistKey").getValue());
    assertEquals(1, this.listenerAfterCommit);
    // Test enlistment for get
    assertEquals(1, this.listenerAfterCommit);
    userTx.begin();
    assertEquals("enlistVal", this.region.get("enlistKey"));
    assertNotNull(this.txMgr.getTransactionId());
    userTx.commit();
    assertNull(this.txMgr.getTransactionId());
    assertEquals(2, this.listenerAfterCommit);
    // Test enlistment for invalidate
    assertEquals(2, this.listenerAfterCommit);
    userTx.begin();
    this.region.invalidate("enlistKey");
    assertTrue(this.region.containsKey("enlistKey"));
    assertTrue(!this.region.containsValueForKey("enlistKey"));
    assertNotNull(this.txMgr.getTransactionId());
    userTx.commit();
    assertNull(this.txMgr.getTransactionId());
    assertTrue(this.region.containsKey("enlistKey"));
    assertTrue(!this.region.containsValueForKey("enlistKey"));
    assertEquals(3, this.listenerAfterCommit);
    // Test enlistment for destroy
    assertEquals(3, this.listenerAfterCommit);
    userTx.begin();
    this.region.destroy("enlistKey");
    assertTrue(!this.region.containsKey("enlistKey"));
    assertNotNull(this.txMgr.getTransactionId());
    userTx.commit();
    assertNull(this.txMgr.getTransactionId());
    assertTrue(!this.region.containsKey("enlistKey"));
    assertEquals(4, this.listenerAfterCommit);
    // Test enlistment for load
    AttributesMutator<String, String> mutator = this.region.getAttributesMutator();
    mutator.setCacheLoader(new CacheLoader<String, String>() {

        int count = 0;

        @Override
        public String load(LoaderHelper helper) throws CacheLoaderException {
            return String.valueOf(count++);
        }

        @Override
        public void close() {
        }
    });
    assertEquals(4, this.listenerAfterCommit);
    userTx.begin();
    assertEquals("0", this.region.get("enlistKey"));
    assertNotNull(this.txMgr.getTransactionId());
    userTx.commit();
    assertNull(this.txMgr.getTransactionId());
    assertTrue(this.region.containsKey("enlistKey"));
    assertEquals("0", this.region.getEntry("enlistKey").getValue());
    assertEquals(5, this.listenerAfterCommit);
    mutator.setCacheLoader(null);
    // Test enlisted failed commit
    assertEquals(0, this.listenerAfterFailedCommit);
    userTx.begin();
    this.region.put("enlistKey", "enlistVal");
    assertEquals("enlistVal", this.region.get("enlistKey"));
    assertNotNull(this.txMgr.getTransactionId());
    {
        TXManagerImpl gfTxMgrImpl = (TXManagerImpl) this.txMgr;
        TXStateProxy gfTx = gfTxMgrImpl.internalSuspend();
        javax.transaction.TransactionManager jtaTxMgr = this.cache.getJTATransactionManager();
        javax.transaction.Transaction jtaTx = jtaTxMgr.suspend();
        this.region.put("enlistKey", "conflictVal");
        assertEquals("conflictVal", this.region.get("enlistKey"));
        try {
            jtaTxMgr.resume(jtaTx);
        } catch (Exception failure) {
            fail("JTA resume failed");
        }
        gfTxMgrImpl.internalResume(gfTx);
    }
    assertEquals("enlistVal", this.region.get("enlistKey"));
    try {
        userTx.commit();
        fail("Expected JTA commit exception!");
    } catch (javax.transaction.HeuristicRollbackException expected) {
    } catch (javax.transaction.RollbackException alsoExpected) {
    } catch (Exception yuk) {
        fail("Did not expect this exception from JTA commit: " + yuk);
    }
    assertNull(this.txMgr.getTransactionId());
    assertEquals("conflictVal", this.region.getEntry("enlistKey").getValue());
    assertEquals(1, this.listenerAfterFailedCommit);
    // Test rollbackOnly UserTransaction enlistment
    userTx.begin();
    assertNull(this.txMgr.getTransactionId());
    userTx.setRollbackOnly();
    assertEquals(javax.transaction.Status.STATUS_MARKED_ROLLBACK, userTx.getStatus());
    try {
        this.region.put("enlistKey", "enlistVal2");
        fail("Expected to get a FailedSynchronizationException!");
    } catch (FailedSynchronizationException okay) {
    }
    assertNull(this.txMgr.getTransactionId());
    try {
        assertEquals("conflictVal", this.region.getEntry("enlistKey").getValue());
        fail("Expected to get a FailedSynchronizationException!");
    } catch (FailedSynchronizationException okay) {
    }
    assertTrue(!this.region.containsKey("enlistKey2"));
    try {
        this.region.put("enlistKey2", "enlistVal3");
        fail("Expected to get a FailedSynchronizationException!");
    } catch (FailedSynchronizationException okay) {
    }
    assertNull(this.txMgr.getTransactionId());
    try {
        assertEquals("conflictVal", this.region.getEntry("enlistKey").getValue());
        fail("Expected to get a FailedSynchronizationException!");
    } catch (FailedSynchronizationException okay) {
    }
    assertTrue(!this.region.containsKey("enlistKey2"));
    userTx.rollback();
    assertEquals("conflictVal", this.region.getEntry("enlistKey").getValue());
    assertTrue(!this.region.containsKey("enlistKey2"));
    this.txMgr.removeListener(tl);
}
Also used : TransactionListener(org.apache.geode.cache.TransactionListener) TXManagerImpl(org.apache.geode.internal.cache.TXManagerImpl) TimeoutException(org.apache.geode.cache.TimeoutException) EntryExistsException(org.apache.geode.cache.EntryExistsException) EntryNotFoundException(org.apache.geode.cache.EntryNotFoundException) CacheWriterException(org.apache.geode.cache.CacheWriterException) TransactionException(org.apache.geode.cache.TransactionException) CacheLoaderException(org.apache.geode.cache.CacheLoaderException) UnsupportedOperationInTransactionException(org.apache.geode.cache.UnsupportedOperationInTransactionException) FailedSynchronizationException(org.apache.geode.cache.FailedSynchronizationException) NoSuchElementException(java.util.NoSuchElementException) CacheException(org.apache.geode.cache.CacheException) CommitConflictException(org.apache.geode.cache.CommitConflictException) QueryException(org.apache.geode.cache.query.QueryException) LoaderHelper(org.apache.geode.cache.LoaderHelper) TransactionEvent(org.apache.geode.cache.TransactionEvent) FailedSynchronizationException(org.apache.geode.cache.FailedSynchronizationException) TXStateProxy(org.apache.geode.internal.cache.TXStateProxy) CacheLoaderException(org.apache.geode.cache.CacheLoaderException) CacheTransactionManager(org.apache.geode.cache.CacheTransactionManager) Test(org.junit.Test) IntegrationTest(org.apache.geode.test.junit.categories.IntegrationTest)

Aggregations

TXStateProxy (org.apache.geode.internal.cache.TXStateProxy)37 TXManagerImpl (org.apache.geode.internal.cache.TXManagerImpl)20 Test (org.junit.Test)9 CommitConflictException (org.apache.geode.cache.CommitConflictException)8 IntegrationTest (org.apache.geode.test.junit.categories.IntegrationTest)8 IOException (java.io.IOException)6 TransactionException (org.apache.geode.cache.TransactionException)6 InternalCache (org.apache.geode.internal.cache.InternalCache)6 LocalRegion (org.apache.geode.internal.cache.LocalRegion)6 InternalGemFireError (org.apache.geode.InternalGemFireError)5 CacheLoaderException (org.apache.geode.cache.CacheLoaderException)5 EntryExistsException (org.apache.geode.cache.EntryExistsException)5 InternalDistributedMember (org.apache.geode.distributed.internal.membership.InternalDistributedMember)5 PartitionedRegion (org.apache.geode.internal.cache.PartitionedRegion)5 CacheWriterException (org.apache.geode.cache.CacheWriterException)4 EntryNotFoundException (org.apache.geode.cache.EntryNotFoundException)4 Region (org.apache.geode.cache.Region)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 ResourceException (javax.resource.ResourceException)3