Example #1
0
  private void sendBatchXA() {
    try {
      sendMessages();

      // Commit the JTA transaction and start another

      delistResources(tx);

      if (JMSBridgeImpl.trace) {
        HornetQJMSServerLogger.LOGGER.trace("Committing JTA transaction");
      }

      tx.commit();

      if (JMSBridgeImpl.trace) {
        HornetQJMSServerLogger.LOGGER.trace("Committed JTA transaction");
      }

      tx = startTx();

      enlistResources(tx);

      // Clear the messages
      messages.clear();
    } catch (Exception e) {
      HornetQJMSServerLogger.LOGGER.bridgeAckError(e);

      handleFailureOnSend();
    }
  }
Example #2
0
  /*
   * Source and target on same server
   * --------------------------------
   * If the source and target destinations are on the same server (same resource manager) then,
   * in order to get ONCE_AND_ONLY_ONCE, we simply need to consuming and send in a single
   * local JMS transaction.
   *
   * We actually use a single local transacted session for the other QoS modes too since this
   * is more performant than using DUPS_OK_ACKNOWLEDGE or AUTO_ACKNOWLEDGE session ack modes, so effectively
   * the QoS is upgraded.
   *
   * Source and target on different server
   * -------------------------------------
   * If the source and target destinations are on a different servers (different resource managers) then:
   *
   * If desired QoS is ONCE_AND_ONLY_ONCE, then we start a JTA transaction and enlist the consuming and sending
   * XAResources in that.
   *
   * If desired QoS is DUPLICATES_OK then, we use CLIENT_ACKNOWLEDGE for the consuming session and
   * AUTO_ACKNOWLEDGE (this is ignored) for the sending session if the maxBatchSize == 1, otherwise we
   * use a local transacted session for the sending session where maxBatchSize > 1, since this is more performant
   * When bridging a batch, we make sure to manually acknowledge the consuming session, if it is CLIENT_ACKNOWLEDGE
   * *after* the batch has been sent
   *
   * If desired QoS is AT_MOST_ONCE then, if maxBatchSize == 1, we use AUTO_ACKNOWLEDGE for the consuming session,
   * and AUTO_ACKNOWLEDGE for the sending session.
   * If maxBatchSize > 1, we use CLIENT_ACKNOWLEDGE for the consuming session and a local transacted session for the
   * sending session.
   *
   * When bridging a batch, we make sure to manually acknowledge the consuming session, if it is CLIENT_ACKNOWLEDGE
   * *before* the batch has been sent
   *
   */
  private boolean setupJMSObjects() {
    try {
      if (sourceCff == targetCff) {
        // Source and target destinations are on the server - we can get once and only once
        // just using a local transacted session
        // everything becomes once and only once

        forwardMode = JMSBridgeImpl.FORWARD_MODE_LOCALTX;
      } else {
        // Different servers
        if (qualityOfServiceMode == QualityOfServiceMode.ONCE_AND_ONLY_ONCE) {
          // Use XA

          forwardMode = JMSBridgeImpl.FORWARD_MODE_XA;
        } else {
          forwardMode = JMSBridgeImpl.FORWARD_MODE_NONTX;
        }
      }

      // Lookup the destinations
      sourceDestination = sourceDestinationFactory.createDestination();

      targetDestination = targetDestinationFactory.createDestination();

      if (forwardMode == JMSBridgeImpl.FORWARD_MODE_LOCALTX) {
        // We simply use a single local transacted session for consuming and sending

        sourceConn = createConnection(sourceUsername, sourcePassword, sourceCff, clientID, false);
        sourceSession = sourceConn.createSession(true, Session.SESSION_TRANSACTED);
      } else {
        if (forwardMode == JMSBridgeImpl.FORWARD_MODE_XA) {
          // Create an XASession for consuming from the source
          if (JMSBridgeImpl.trace) {
            HornetQJMSServerLogger.LOGGER.trace("Creating XA source session");
          }

          sourceConn = createConnection(sourceUsername, sourcePassword, sourceCff, clientID, true);
          sourceSession = ((XAConnection) sourceConn).createXASession();
        } else {
          if (JMSBridgeImpl.trace) {
            HornetQJMSServerLogger.LOGGER.trace("Creating non XA source session");
          }

          // Create a standard session for consuming from the source

          // We use ack mode client ack

          sourceConn = createConnection(sourceUsername, sourcePassword, sourceCff, clientID, false);
          sourceSession = sourceConn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
        }
      }

      if (subName == null) {
        if (selector == null) {
          sourceConsumer = sourceSession.createConsumer(sourceDestination);
        } else {
          sourceConsumer = sourceSession.createConsumer(sourceDestination, selector, false);
        }
      } else {
        // Durable subscription
        if (selector == null) {
          sourceConsumer =
              sourceSession.createDurableSubscriber((Topic) sourceDestination, subName);
        } else {
          sourceConsumer =
              sourceSession.createDurableSubscriber(
                  (Topic) sourceDestination, subName, selector, false);
        }
      }

      // Now the sending session

      if (forwardMode == JMSBridgeImpl.FORWARD_MODE_LOCALTX) {
        targetConn = sourceConn;
        targetSession = sourceSession;
      } else {
        if (forwardMode == JMSBridgeImpl.FORWARD_MODE_XA) {
          if (JMSBridgeImpl.trace) {
            HornetQJMSServerLogger.LOGGER.trace("Creating XA dest session");
          }

          // Create an XA sesion for sending to the destination

          targetConn = createConnection(targetUsername, targetPassword, targetCff, null, true);

          targetSession = ((XAConnection) targetConn).createXASession();
        } else {
          if (JMSBridgeImpl.trace) {
            HornetQJMSServerLogger.LOGGER.trace("Creating non XA dest session");
          }

          // Create a standard session for sending to the target

          // If batch size > 1 we use a transacted session since is more efficient

          boolean transacted = maxBatchSize > 1;

          targetConn = createConnection(targetUsername, targetPassword, targetCff, null, false);

          targetSession =
              targetConn.createSession(
                  transacted, transacted ? Session.SESSION_TRANSACTED : Session.AUTO_ACKNOWLEDGE);
        }
      }

      if (forwardMode == JMSBridgeImpl.FORWARD_MODE_XA) {
        if (JMSBridgeImpl.trace) {
          HornetQJMSServerLogger.LOGGER.trace("Starting JTA transaction");
        }

        tx = startTx();

        enlistResources(tx);
      }

      targetProducer = targetSession.createProducer(null);

      return true;
    } catch (Exception e) {
      // We shouldn't log this, as it's expected when trying to connect when target/source is not
      // available

      // If this fails we should attempt to cleanup or we might end up in some weird state

      // Adding a log.warn, so the use may see the cause of the failure and take actions
      HornetQJMSServerLogger.LOGGER.bridgeConnectError(e);

      cleanup();

      return false;
    }
  }