public synchronized void xaPrepare(final Xid xid) throws Exception { if (tx != null && tx.getXid().equals(xid)) { final String msg = "Cannot commit, session is currently doing work in a transaction " + tx.getXid(); throw new HornetQXAException(XAException.XAER_PROTO, msg); } else { Transaction theTx = resourceManager.getTransaction(xid); if (isTrace) { HornetQLogger.LOGGER.trace("xaprepare into " + ", xid=" + xid + ", tx= " + tx); } if (theTx == null) { final String msg = "Cannot find xid in resource manager: " + xid; throw new HornetQXAException(XAException.XAER_NOTA, msg); } else { if (theTx.getState() == Transaction.State.SUSPENDED) { throw new HornetQXAException( XAException.XAER_PROTO, "Cannot prepare transaction, it is suspended " + xid); } else if (theTx.getState() == Transaction.State.PREPARED) { HornetQLogger.LOGGER.info("ignoring prepare on xid as already called :" + xid); } else { theTx.prepare(); } } } }
public synchronized void xaStart(final Xid xid) throws Exception { if (tx != null) { HornetQServerLogger.LOGGER.xidReplacedOnXStart(tx.getXid().toString(), xid.toString()); try { if (tx.getState() != Transaction.State.PREPARED) { // we don't want to rollback anything prepared here if (tx.getXid() != null) { resourceManager.removeTransaction(tx.getXid()); } tx.rollback(); } } catch (Exception e) { HornetQServerLogger.LOGGER.debug( "An exception happened while we tried to debug the previous tx, we can ignore this exception", e); } } tx = newTransaction(xid); if (isTrace) { HornetQServerLogger.LOGGER.trace("xastart into tx= " + tx); } boolean added = resourceManager.putTransaction(xid, tx); if (!added) { final String msg = "Cannot start, there is already a xid " + tx.getXid(); throw new HornetQXAException(XAException.XAER_DUPID, msg); } }
public synchronized void xaResume(final Xid xid) throws Exception { if (tx != null) { final String msg = "Cannot resume, session is currently doing work in a transaction " + tx.getXid(); throw new HornetQXAException(XAException.XAER_PROTO, msg); } else { Transaction theTx = resourceManager.getTransaction(xid); if (theTx == null) { final String msg = "Cannot find xid in resource manager: " + xid; throw new HornetQXAException(XAException.XAER_NOTA, msg); } else { if (theTx.getState() != Transaction.State.SUSPENDED) { throw new HornetQXAException( XAException.XAER_PROTO, "Cannot resume transaction, it is not suspended " + xid); } else { tx = theTx; tx.resume(); } } } }
public synchronized void xaRollback(final Xid xid) throws Exception { if (tx != null && tx.getXid().equals(xid)) { final String msg = "Cannot roll back, session is currently doing work in a transaction " + tx.getXid(); throw new HornetQXAException(XAException.XAER_PROTO, msg); } else { Transaction theTx = resourceManager.removeTransaction(xid); if (isTrace) { HornetQLogger.LOGGER.trace("xarollback into " + theTx); } if (theTx == null) { // checked heuristic committed transactions if (resourceManager.getHeuristicCommittedTransactions().contains(xid)) { throw new HornetQXAException( XAException.XA_HEURCOM, "transaction has ben heuristically committed: " + xid); } // checked heuristic rolled back transactions else if (resourceManager.getHeuristicRolledbackTransactions().contains(xid)) { throw new HornetQXAException( XAException.XA_HEURRB, "transaction has ben heuristically rolled back: " + xid); } else { if (isTrace) { HornetQLogger.LOGGER.trace( "xarollback into " + theTx + ", xid=" + xid + " forcing a rollback regular"); } try { // jbpapp-8845 // This could have happened because the TX timed out, // at this point we would be better on rolling back this session as a way to prevent // consumers from holding their messages this.rollback(false); } catch (Exception e) { HornetQLogger.LOGGER.warn(e.getMessage(), e); } throw new HornetQXAException( XAException.XAER_NOTA, "Cannot find xid in resource manager: " + xid); } } else { if (theTx.getState() == Transaction.State.SUSPENDED) { if (isTrace) { HornetQLogger.LOGGER.trace( "xarollback into " + theTx + " sending tx back as it was suspended"); } // Put it back resourceManager.putTransaction(xid, tx); throw new HornetQXAException( XAException.XAER_PROTO, "Cannot rollback transaction, it is suspended " + xid); } else { doRollback(false, false, theTx); } } } }
public synchronized void xaEnd(final Xid xid) throws Exception { if (tx != null && tx.getXid().equals(xid)) { if (tx.getState() == Transaction.State.SUSPENDED) { final String msg = "Cannot end, transaction is suspended"; throw new HornetQXAException(XAException.XAER_PROTO, msg); } else if (tx.getState() == Transaction.State.ROLLEDBACK) { final String msg = "Cannot end, transaction is rolled back"; tx = null; throw new HornetQXAException(XAException.XAER_PROTO, msg); } else { tx = null; } } else { // It's also legal for the TM to call end for a Xid in the suspended // state // See JTA 1.1 spec 3.4.4 - state diagram // Although in practice TMs rarely do this. Transaction theTx = resourceManager.getTransaction(xid); if (theTx == null) { final String msg = "Cannot find suspended transaction to end " + xid; throw new HornetQXAException(XAException.XAER_NOTA, msg); } else { if (theTx.getState() != Transaction.State.SUSPENDED) { final String msg = "Transaction is not suspended " + xid; throw new HornetQXAException(XAException.XAER_PROTO, msg); } else { theTx.resume(); } } } }
public synchronized void xaJoin(final Xid xid) throws Exception { Transaction theTx = resourceManager.getTransaction(xid); if (theTx == null) { final String msg = "Cannot find xid in resource manager: " + xid; throw new HornetQXAException(XAException.XAER_NOTA, msg); } else { if (theTx.getState() == Transaction.State.SUSPENDED) { throw new HornetQXAException( XAException.XAER_PROTO, "Cannot join tx, it is suspended " + xid); } else { tx = theTx; } } }
public synchronized void xaCommit(final Xid xid, final boolean onePhase) throws Exception { if (tx != null && tx.getXid().equals(xid)) { final String msg = "Cannot commit, session is currently doing work in transaction " + tx.getXid(); throw new HornetQXAException(XAException.XAER_PROTO, msg); } else { Transaction theTx = resourceManager.removeTransaction(xid); if (isTrace) { HornetQLogger.LOGGER.trace("XAcommit into " + theTx + ", xid=" + xid); } if (theTx == null) { // checked heuristic committed transactions if (resourceManager.getHeuristicCommittedTransactions().contains(xid)) { throw new HornetQXAException( XAException.XA_HEURCOM, "transaction has been heuristically committed: " + xid); } // checked heuristic rolled back transactions else if (resourceManager.getHeuristicRolledbackTransactions().contains(xid)) { throw new HornetQXAException( XAException.XA_HEURRB, "transaction has been heuristically rolled back: " + xid); } else { if (isTrace) { HornetQLogger.LOGGER.trace( "XAcommit into " + theTx + ", xid=" + xid + " cannot find it"); } throw new HornetQXAException( XAException.XAER_NOTA, "Cannot find xid in resource manager: " + xid); } } else { if (theTx.getState() == Transaction.State.SUSPENDED) { // Put it back resourceManager.putTransaction(xid, theTx); throw new HornetQXAException( XAException.XAER_PROTO, "Cannot commit transaction, it is suspended " + xid); } else { theTx.commit(onePhase); } } } }
public void individualAcknowledge(final long consumerID, final long messageID) throws Exception { ServerConsumer consumer = consumers.get(consumerID); if (this.xa && tx == null) { throw new HornetQXAException(XAException.XAER_PROTO, "Invalid transaction state"); } if (tx != null && tx.getState() == State.ROLLEDBACK) { // JBPAPP-8845 - if we let stuff to be acked on a rolled back TX, we will just // have these messages to be stuck on the limbo until the server is restarted // The tx has already timed out, so we need to ack and rollback immediately Transaction newTX = newTransaction(); consumer.individualAcknowledge(autoCommitAcks, tx, messageID); newTX.rollback(); } else { consumer.individualAcknowledge(autoCommitAcks, tx, messageID); } }
public void acknowledge(final long consumerID, final long messageID) throws Exception { ServerConsumer consumer = consumers.get(consumerID); if (consumer == null) { throw HornetQMessageBundle.BUNDLE.consumerDoesntExist(consumerID); } if (tx != null && tx.getState() == State.ROLLEDBACK) { // JBPAPP-8845 - if we let stuff to be acked on a rolled back TX, we will just // have these messages to be stuck on the limbo until the server is restarted // The tx has already timed out, so we need to ack and rollback immediately Transaction newTX = newTransaction(); consumer.acknowledge(autoCommitAcks, newTX, messageID); newTX.rollback(); } else { consumer.acknowledge(autoCommitAcks, tx, messageID); } }
public synchronized void xaSuspend() throws Exception { if (isTrace) { HornetQLogger.LOGGER.trace("xasuspend on " + this.tx); } if (tx == null) { final String msg = "Cannot suspend, session is not doing work in a transaction "; throw new HornetQXAException(XAException.XAER_PROTO, msg); } else { if (tx.getState() == Transaction.State.SUSPENDED) { final String msg = "Cannot suspend, transaction is already suspended " + tx.getXid(); throw new HornetQXAException(XAException.XAER_PROTO, msg); } else { tx.suspend(); tx = null; } } }