/**
  * Determine whether the given JMS Session is transactional, that is, bound to the current thread
  * by Spring's transaction facilities.
  *
  * @param session the JMS Session to check
  * @param cf the JMS ConnectionFactory that the Session originated from
  * @return whether the Session is transactional
  */
 public static boolean isSessionTransactional(Session session, ConnectionFactory cf) {
   if (session == null || cf == null) {
     return false;
   }
   JmsResourceHolder resourceHolder =
       (JmsResourceHolder) TransactionSynchronizationManager.getResource(cf);
   return (resourceHolder != null && resourceHolder.containsSession(session));
 }
 protected void processResourceAfterCommit(JmsResourceHolder resourceHolder) {
   try {
     resourceHolder.commitAll();
   } catch (JMSException ex) {
     throw new SynchedLocalTransactionFailedException(
         "Local JMS transaction failed to commit", ex);
   }
 }
 protected void releaseResource(JmsResourceHolder resourceHolder, Object resourceKey) {
   resourceHolder.closeAll();
 }
  /**
   * Obtain a JMS Session that is synchronized with the current transaction, if any.
   *
   * @param connectionFactory the JMS ConnectionFactory to bind for (used as
   *     TransactionSynchronizationManager key)
   * @param resourceFactory the ResourceFactory to use for extracting or creating JMS resources
   * @param startConnection whether the underlying JMS Connection approach should be started in
   *     order to allow for receiving messages. Note that a reused Connection may already have been
   *     started before, even if this flag is {@code false}.
   * @return the transactional Session, or {@code null} if none found
   * @throws JMSException in case of JMS failure
   */
  public static Session doGetTransactionalSession(
      ConnectionFactory connectionFactory, ResourceFactory resourceFactory, boolean startConnection)
      throws JMSException {

    Assert.notNull(connectionFactory, "ConnectionFactory must not be null");
    Assert.notNull(resourceFactory, "ResourceFactory must not be null");

    JmsResourceHolder resourceHolder =
        (JmsResourceHolder) TransactionSynchronizationManager.getResource(connectionFactory);
    if (resourceHolder != null) {
      Session session = resourceFactory.getSession(resourceHolder);
      if (session != null) {
        if (startConnection) {
          Connection con = resourceFactory.getConnection(resourceHolder);
          if (con != null) {
            con.start();
          }
        }
        return session;
      }
      if (resourceHolder.isFrozen()) {
        return null;
      }
    }
    if (!TransactionSynchronizationManager.isSynchronizationActive()) {
      return null;
    }
    JmsResourceHolder resourceHolderToUse = resourceHolder;
    if (resourceHolderToUse == null) {
      resourceHolderToUse = new JmsResourceHolder(connectionFactory);
    }
    Connection con = resourceFactory.getConnection(resourceHolderToUse);
    Session session = null;
    try {
      boolean isExistingCon = (con != null);
      if (!isExistingCon) {
        con = resourceFactory.createConnection();
        resourceHolderToUse.addConnection(con);
      }
      session = resourceFactory.createSession(con);
      resourceHolderToUse.addSession(session, con);
      if (startConnection) {
        con.start();
      }
    } catch (JMSException ex) {
      if (session != null) {
        try {
          session.close();
        } catch (Throwable ex2) {
          // ignore
        }
      }
      if (con != null) {
        try {
          con.close();
        } catch (Throwable ex2) {
          // ignore
        }
      }
      throw ex;
    }
    if (resourceHolderToUse != resourceHolder) {
      TransactionSynchronizationManager.registerSynchronization(
          new JmsResourceSynchronization(
              resourceHolderToUse,
              connectionFactory,
              resourceFactory.isSynchedLocalTransactionAllowed()));
      resourceHolderToUse.setSynchronizedWithTransaction(true);
      TransactionSynchronizationManager.bindResource(connectionFactory, resourceHolderToUse);
    }
    return session;
  }