Пример #1
0
  private void doRollback(
      final boolean clientFailed, final boolean lastMessageAsDelived, final Transaction theTx)
      throws Exception {
    boolean wasStarted = started;

    List<MessageReference> toCancel = new ArrayList<MessageReference>();

    for (ServerConsumer consumer : consumers.values()) {
      if (wasStarted) {
        consumer.setStarted(false);
      }

      toCancel.addAll(consumer.cancelRefs(clientFailed, lastMessageAsDelived, theTx));
    }

    for (MessageReference ref : toCancel) {
      ref.getQueue().cancel(theTx, ref);
    }

    if (wasStarted) {
      theTx.addOperation(
          new TransactionOperationAbstract() {

            public void afterRollback(Transaction tx) {
              for (ServerConsumer consumer : consumers.values()) {
                consumer.setStarted(true);
              }
            }
          });
    }

    theTx.rollback();
  }
Пример #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
  private void doRollback(
      final boolean clientFailed, final boolean lastMessageAsDelived, final Transaction theTx)
      throws Exception {
    boolean wasStarted = started;

    List<MessageReference> toCancel = new ArrayList<MessageReference>();

    for (ServerConsumer consumer : consumers.values()) {
      if (wasStarted) {
        consumer.setStarted(false);
      }

      toCancel.addAll(consumer.cancelRefs(clientFailed, lastMessageAsDelived, theTx));
    }

    for (MessageReference ref : toCancel) {
      ref.getQueue().cancel(theTx, ref);
    }
    // if we failed don't restart as an attempt to deliver messages may be made before we actually
    // close the consumer
    if (wasStarted && !clientFailed) {
      theTx.addOperation(
          new TransactionOperationAbstract() {

            @Override
            public void afterRollback(Transaction tx) {
              for (ServerConsumer consumer : consumers.values()) {
                consumer.setStarted(true);
              }
            }
          });
    }

    theTx.rollback();
  }
Пример #4
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);
    }
  }
Пример #5
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);
    }
  }
Пример #6
0
  public void acknowledge(final boolean autoCommitAcks, Transaction tx, final long messageID)
      throws Exception {
    if (browseOnly) {
      return;
    }

    // Acknowledge acknowledges all refs delivered by the consumer up to and including the one
    // explicitly
    // acknowledged

    // We use a transaction here as if the message is not found, we should rollback anything done
    // This could eventually happen on retries during transactions, and we need to make sure we
    // don't ACK things we are not supposed to acknowledge

    boolean startedTransaction = false;

    if (tx == null || autoCommitAcks) {
      startedTransaction = true;
      tx = new TransactionImpl(storageManager);
    }

    try {

      MessageReference ref;
      do {
        ref = deliveringRefs.poll();

        if (HornetQServerLogger.LOGGER.isTraceEnabled()) {
          HornetQServerLogger.LOGGER.trace(
              "ACKing ref " + ref + " on tx= " + tx + ", consumer=" + this);
        }

        if (ref == null) {
          throw HornetQMessageBundle.BUNDLE.consumerNoReference(
              id, messageID, messageQueue.getName());
        }

        ref.getQueue().acknowledge(tx, ref);
      } while (ref.getMessage().getMessageID() != messageID);

      if (startedTransaction) {
        tx.commit();
      }
    } catch (HornetQException e) {
      if (startedTransaction) {
        tx.rollback();
      } else {
        tx.markAsRollbackOnly(e);
      }
      throw e;
    } catch (Throwable e) {
      HornetQServerLogger.LOGGER.errorAckingMessage((Exception) e);
      HornetQException hqex = new HornetQIllegalStateException(e.getMessage());
      if (startedTransaction) {
        tx.rollback();
      } else {
        tx.markAsRollbackOnly(hqex);
      }
      throw hqex;
    }
  }
Пример #7
0
  public void close(final boolean failed) throws Exception {
    callback.removeReadyListener(this);

    setStarted(false);

    LargeMessageDeliverer del = largeMessageDeliverer;

    if (del != null) {
      del.finish();
    }

    if (browseOnly) {
      browserDeliverer.close();
    } else {
      messageQueue.removeConsumer(this);
    }

    session.removeConsumer(id);

    LinkedList<MessageReference> refs = cancelRefs(failed, false, null);

    Iterator<MessageReference> iter = refs.iterator();

    Transaction tx = new TransactionImpl(storageManager);

    while (iter.hasNext()) {
      MessageReference ref = iter.next();

      ref.getQueue().cancel(tx, ref);
    }

    tx.rollback();

    if (!browseOnly) {
      TypedProperties props = new TypedProperties();

      props.putSimpleStringProperty(ManagementHelper.HDR_ADDRESS, binding.getAddress());

      props.putSimpleStringProperty(ManagementHelper.HDR_CLUSTER_NAME, binding.getClusterName());

      props.putSimpleStringProperty(ManagementHelper.HDR_ROUTING_NAME, binding.getRoutingName());

      props.putSimpleStringProperty(
          ManagementHelper.HDR_FILTERSTRING, filter == null ? null : filter.getFilterString());

      props.putIntProperty(ManagementHelper.HDR_DISTANCE, binding.getDistance());

      props.putIntProperty(ManagementHelper.HDR_CONSUMER_COUNT, messageQueue.getConsumerCount());

      // HORNETQ-946
      props.putSimpleStringProperty(
          ManagementHelper.HDR_USER, SimpleString.toSimpleString(session.getUsername()));

      props.putSimpleStringProperty(
          ManagementHelper.HDR_REMOTE_ADDRESS,
          SimpleString.toSimpleString(
              ((ServerSessionImpl) session).getRemotingConnection().getRemoteAddress()));

      props.putSimpleStringProperty(
          ManagementHelper.HDR_SESSION_NAME, SimpleString.toSimpleString(session.getName()));

      Notification notification = new Notification(null, NotificationType.CONSUMER_CLOSED, props);

      managementService.sendNotification(notification);
    }
  }