У меня есть два 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?