在我的Java EE应用程序中,我实现了一个异步数据库记录器作为MDB,它通过JMS接收XML消息并将其写入数据库。
在另一个 MDB 中,我使用以下代码创建一条日志消息并将它们发送到记录器 MDB 的输入队列:
public static void log(String correlId, String message, String data) throws Exception{
SysLogEntry sysLogEntry = new SysLogEntry();
sysLogEntry.setCorrelId(correlId);
sysLogEntry.setDatetimeCreate(new Date());
sysLogEntry.setMessage(message);
sysLogEntry.setData(data);
ConnectionFactory jmsConnectionFactory = (ConnectionFactory)initialContext.lookup(JMS_CONNECTION_FACTORY_JNDI_NAME);
Destination logEventDestination = (Destination) initialContext.lookup(LOG_EVENT_DESTINATION_JNDI_NAME);
JmsUtils.sendMsgToDestination(JaxbUtils.toString(sysLogEntry, jaxbContext), jmsConnectionFactory, logEventDestination, false, Session.AUTO_ACKNOWLEDGE);
}
public static void sendMsgToDestination(String payload, ConnectionFactory connFactory, Destination destination, boolean sessionTransacted, int acknowledgeMode) throws JMSException{
if(payload == null)
throw new IllegalArgumentException("Message payload is null");
if(connFactory == null)
throw new IllegalArgumentException("Connection factory is null");
if(destination == null)
throw new IllegalArgumentException("Message destination is null");
Connection connection = null;
try{
connection = connFactory.createConnection();
Session session = connection.createSession(sessionTransacted, acknowledgeMode);
MessageProducer messageProducer = session.createProducer(destination);
TextMessage textMessage = session.createTextMessage();
textMessage.setText(payload);
messageProducer.send(textMessage);
} finally {
if(connection != null){
try{
connection.close();
} catch (JMSException ignore){
}
}
}
}
哪里
SysLogEntry
是一个带有 JAXB 注释的类,我用它来序列化JMS_CONNECTION_FACTORY_JNDI_NAME
是 XA 连接工厂的 JNDI 名称但是,每次回滚创建日志消息的事务时,日志消息都不会放入记录器输入队列。
有人可以告诉我我的代码出了什么问题吗?我考虑过使用一个单独的无状态会话 bean,它将启动一个新的事务来生成日志消息,但这种方法有一个缺点:在 EJB 内部,我可以轻松地让容器注入记录器 bean,但我也有非 EJB 对象,我想在其中执行异步日志记录。
我的应用程序服务器是Weblogic 10.3.3
我将创建一个单独的 Bean 来记录消息,并注释 sendMessage 以启动自己的和独立的事务:
java prettyprint-override">@Stateless
public class SenderBean {
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public sendMsgToDestination(String payload, ConnectionFactory connFactory, Destination destination, boolean sessionTransacted, int acknowledgeMode) throws JMSException{
...
Connection connection = null;
try(
connection = connFactory.createConnection();
Session session = connection.createSession(sessionTransacted, acknowledgeMode);
){
MessageProducer messageProducer = session.createProducer(destination);
TextMessage textMessage = session.createTextMessage();
textMessage.setText(payload);
messageProducer.send(textMessage);
}
}
然后我会使用这个 BEAN 进行日志记录,即使您的调用方事务被回滚,它也会将消息写入队列
可以将包含静态日志方法的类的静态成员分配给无状态 EJB 代理的实例。代理本身只是将调用路由到实例池中的空闲 Bean,因此可以静态共享它。
但。。。启动新事务只是为了逃避当前事务听起来很浪费。特别是如果频繁记录此异步记录器,您可能希望以不同的方式执行此操作。
使用一个简单的Java SE执行器池和几个线程,然后向该池提交工作(一个可运行)。在这个可运行代码中,您仍然可以发送 JMS 消息,保持现有代码不变。当池中的线程接听工作时,事务上下文将丢失,但这正是您首先需要的。
如果发生系统异常(或 sessionContext.setRollbackOnly
),则全局事务将由容器回滚(如果使用容器管理的事务)。这意味着对全局事务中登记的 XA 感知资源的任何操作都将回滚。
在您的情况下,这包括要发送到记录器的待处理消息。这个被删除,因为事务被回滚。
在您的情况下,如果您使用非 XA 连接工厂,这应该就足够了。这样,消息应该立即发送(在记录器甚至有帮助的情况下)。因此,发送仅在跨越 JMS 发送任务的本地事务中运行。
至于非 EJB 对象:您可以使用非 XA 连接工厂将发送功能提取到普通的 Java 类(= 不是 EJB)中,并从 EJB 和普通类中使用它。
null 谁能给我一个向RabbitMQ发送消息的标准程序的例子。我正在使用Spring Boot,也可以使用它的特性。
我想使用SpringBoot向ActiveMQ队列发送消息。应用程序应在发送后终止,但仍保持活动状态。 这是我的申请代码: 在没有任何父节点的情况下使用以下依赖项(Maven): 和一行
Azure服务总线可以发送计划的消息。使用此处描述的AMQP协议发送计划消息:https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-amqp-request-response#message-operations 调度消息。要求 请求消息必须包括以下应用程序属性: |键|值|类型|必需|值内容 |操作|字符
问题内容: 我正在尝试创建一个Java Application Client项目,该项目将JMS消息发送到Glassfish服务器上的队列。 问题在于,应用发送完消息后,它在应退出时挂起。该消息已成功传输,但是由于某种原因该应用程序没有退出。我已经尝试调试该应用程序,并且可以将其一直走到的结尾,这就是它的挂起位置。 这是代码: 如何使其停止挂起? 问题答案: 长期以来,它一直是Glassfish中
如何延迟JMS消息发送或在不确定的时间内继续? 我使用的是Weblogic,正如您所知,在JMS发送之后,接收方将异步处理消息,但是,此时或有时外部资源还没有为接收方做好准备,因此,我想使用一些检查逻辑来延迟发送或处理消息。我猜例如:我将消息放入挂起队列,然后频繁检查资源可用性,一旦发送或继续消息? 大家都知道Weblogic是否支持这一点,或者如何实现它吗?
我们有一个Spring Boot应用程序,用于在另一个组件上执行负载测试。我们每分钟最多需要发送35000条JMS消息,因此我使用调度器每分钟运行一次任务。 问题是当我保持低强度时,它会设法在指定的时间间隔(一分钟)内发送消息。但是当强度很高时,发送消息块需要超过1分钟。对以下实现有任何建议吗? 调度程序类 用于发送消息的类
我是Spring JMS的新手。我的应用程序是使用Spring Boot开发的,并部署在JBoss EAP7.2.0中。我有一个远程队列,它是一个活动的MQ Artemis队列,也嵌入在JBoss EAP7.2.0中。有人能建议我如何使用Spring Boot的JmsTemplate向远程JMS队列发送消息吗?基本上,我不知道应该如何定义远程connectionFactory来连接到远程队列。
最近,我不得不支持一位同事验证为什么一些系统测试没有通过wildfly,即在weblogic和glass fish上一致通过的系统测试。 分析日志后,很明显,原因与受支持线程发送的JMS消息过早提交到队列有关,当时的期望是当MDB的切入点容器托管事务提交时消息将被提交。因此,在发送消息的MDB运行完成之前,消息会发出。 在weblogic中,为了实现预期的行为,需要确保在获取容器(已配置XA)提供