示例#1
0
  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();
        }
      }
    }
  }
示例#2
0
  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);
    }
  }
示例#3
0
  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();
        }
      }
    }
  }
示例#4
0
  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);
        }
      }
    }
  }
示例#5
0
  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();
        }
      }
    }
  }
示例#6
0
  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;
      }
    }
  }
示例#7
0
  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);
        }
      }
    }
  }
示例#8
0
  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);
    }
  }
示例#9
0
  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);
    }
  }
示例#10
0
  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;
      }
    }
  }