Могу ли я писать и читать сообщения из очереди в bean-компонентах, описанных в одном ejb-jar? - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть два EJB, которые описаны в одном файле ejb-jar.xml.Первый - компонент без сохранения состояния и помещает сообщение в очередь сообщений WebSpheres с созданным вручную соединением.

@Remote({ Producer.class })
public class ProducerImpl implements Producer, Serializable {
  @Override
  public boolean send(ObjectNode json) {
    try {
        Connection connection = queueCF.createConnection();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        MessageProducer producer = session.createProducer(queue);
        TextMessage message = session.createTextMessage();

        message.setText(json.toString());
        producer.send(message);
        return true;
    } catch (JMSException e) {
        sysLog.log(...);
        return false;
    }
  }
}

Второй - MDB и читает из этой очереди.

public class Consumer implements MessageListener {
  @Override
  public void onMessage (Message message) {
      try {
          sendToUrl((TextMessage)message);
      } catch (JMSException | IOException e) {
          log.log(Level.SEVERE, e.getMessage(), e);
      }
  }
}

EJB-jar.xml выглядит следующим образом (некоторые элементы env-entry опущены):

<enterprise-beans>
    <session>
        <ejb-name>Producer</ejb-name>
        <ejb-class>com.example.jms.ProducerImpl</ejb-class>
        <session-type>Stateless</session-type>
        <transaction-type>Container</transaction-type>

        <resource-ref>
            <res-ref-name>jms/queue</res-ref-name>
            <res-type>javax.jms.Queue</res-type>
            <res-auth>Container</res-auth>
        </resource-ref>

        <resource-ref>
            <res-ref-name>jms/connectionFactory</res-ref-name>
            <res-type>javax.jms.QueueConnectionFactory</res-type>
            <res-auth>Container</res-auth>
        </resource-ref>
    </session>
    <message-driven>
        <ejb-name>Consumer</ejb-name>
        <mapped-name>jms/queue</mapped-name>
        <ejb-class>com.example.Consumer</ejb-class>
        <transaction-type>Container</transaction-type>
        <activation-config>
            <activation-config-property>
                <activation-config-property-name>destinationLookup</activation-config-property-name>
                <activation-config-property-value>jms/lookup</activation-config-property-value>
            </activation-config-property>
            <activation-config-property>
                <activation-config-property-name>destinationType</activation-config-property-name>
                <activation-config-property-value>javax.jms.Queue</activation-config-property-value>
            </activation-config-property>
        </activation-config>

    </message-driven>
</enterprise-beans>

Проблема в том, что чтение из очереди существует в той же транзакции, что и запись.Почему я так думаю?Я просто попытался вызвать источник, и он не вернулся, пока Consumer :: onMessage не был завершен.

Я попытался пометить Consumer :: onMessage с другим распространением транзакции (NotSupported, requireNew и т. Д.) ИПроизвести потребительскую транзакцию типа «Боб».Но все ничего не изменилось.

Итак, вопрос: могу ли я читать из очереди в рамках совершенно отдельной транзакции, чтобы Producer не стал ждать Consumer?

...