JMS - 事务性消息

JMS 事务遵从发送操作与接收操作相互分离的约定。下图显示的是一个事务性发送,其中一组消息要么能够保证全部到达消息服务器,要么连一条消息也不能保证到达消息服务器。从发送者的角度来看,JMS 提供者为这组消息提供了高速缓存,直到执行 commit() 为止。如果发生了故障,或者执行了 rollback(),这些消息就会丢弃。在一个事务中传送给消息服务器的消息,它并不会转发给消费者,知道该生产者提交该事务为止。

生产者在会话上发布 commit() 之前,JMS 提供者不会开始向它的消费者传送消息,即使它已经从发送者处接收到所有的消息。JMS 事务的范围能够包括任意数量的消息。虽然会话 commit() 和 JTA(Java Transaction API) 事务 commit() 在概念上类似,但是二者并不相同。会话事务是由 JMS 提供者管理的,而不是由 JTA 管理的。

JMS 还支持事务性接收,消费者正在接收一组事务性消息,而且要么全部接收,要么一条也不接收,参考下图。从事务性接收者的角度来看,这些消息会尽可能快地传送给接收者,但是它们一直由 JMS 提供者保存,直到接收者在会话对象上执行 commit() 为止。如果发送了故障,或者执行 rollback(),提供者会试图重新传送消息,在这种情况下,这些消息就会设置重新传送标记。

发送消息,如果在发送消息的方法正常完成后没有调用 Session.commit() 方法,JMS 提供者会从队列中删除这些消息,而这些消息并没有传送给消息消费者。接收消息时,如果在接收消息的方法正常完成后没有调用 Session.commit() 方法,消息就会被标记为未被传送。JMS 提供者会把这些消息重新传送给消息消费者,并将 JMSRedelivered 消息头属性设置为 true,表示此前曾试图处理过这些消息。因此在这两种情况下,都必须注意:要确保在该方法结束之前,提交会话或将其回滚。

Sample Code:

// ...Connection connection = null;
Session session = null;
try {
    Context ctx = new InitialContext();
    ConnectionFactory connFactory = (ConnectionFactory) ctx.lookup("connectionFactory");
    connection = connFactory.createConnection();
    connection.start();

    // 创建会话对象实例,第一个参数表示会话是否是启用事务
    session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);

    Destination destination = (Destination) ctx.lookup("HelloQueue");
    MessageProducer msgProducer = session.createProducer(destination);
    Message textMsg = session.createTextMessage("This is a test message.");
    msgProducer.send(textMsg);

    // 提交事务
    session.commit();
    System.out.println("send the message successfully");
} catch (Exception e) {
    if (session != null) {
        try {
            // 回滚事务
            session.rollback();
        } catch (JMSException jmse) {
            jmse.printStackTrace();
        }
    }
    e.printStackTrace();
} finally {
    JMSUtils.closeConnection(connection);
}// ...
时间: 2024-11-11 15:34:39

JMS - 事务性消息的相关文章

JMS(Java消息服务)入门教程

阅读目录 什么是Java消息服务 为什么需要JMS JMS的优势 JMS消息传送模型 接收消息 JMS编程接口 JMS消息结构 JMS使用示例 译文链接(做了部分修改~~) 什么是Java消息服务 Java消息服务指的是两个应用程序之间进行异步通信的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建.发送.读取消息等,用于支持JAVA应用程序开发.在J2EE中,当两个应用程序使用JMS进行通信时,它们之间并不是直接相连的,而是通过一个共同的消息收发服务连接起来,可以达到解耦的效果,我

JMS异步消息解决分布式应用的EhCache缓存同步问题

上篇博客中讲到了怎样用拦截器给用EJB发布的WebService添加缓存,这样可以提高WebService的响应效率.可是即使是这样做,还是要经历网络的传输的.于是决定在调用WebService的程序本地也添加EJB方法缓存,如果WebService调用的结果已经存在于本地缓存中,就直接从内存中拿数据,不用再访问WebService了. 架构图如下所示 但是另一个问题又出现了,那就是WebService中的缓存和客户程序本地缓存的同步问题,这个问题可以具体描述如下: 当提供WebService的

基于JMS的消息传送

简单的介绍下基于JMS的消息传送 Java消息队列JMS整体设计结构 基本要素:生产者(producer),消费者(consumere),消息服务(broker) 交互模型: JMS两种消息传送模式 点对点(Point-to-Point):专门用于使用队列Queue传送消息: 发布/订阅(Publish/Subscribe):专门用于使用主题Topic传送消息 两种传送方式比较 基于队列Queue的点对点消息只能被一个消费者消费,如多个消费者都注册到同一个消息队列上,当生产者发送一条消息后,而只

RocketMQ事务性消息及持久化

TransactionProducer(事务消息): 在分布式系统中,我们时常会遇到分布式事务的问题,除了常规的解决方案之外,我们还可以利用RocketMQ的事务性消息来解决分布式事务的问题.RocketMQ和其他消息中间件最大的一个区别是支持了事务消息,这也是分布式事务里面的基于消息的最终一致性方案. RocketMQ消息的事务架构设计: 生产者执行本地事务,修改订单支付状态,并且提交事务 生产者发送事务消息到broker上,消息发送到broker上在没有确认之前,消息对于consumer是不

JMS(java消息服务)整合Spring项目案例

转载自云栖社区 摘要: Sprng-jms消息服务小项目 所需的包: spring的基础包 spring-jms-xx包 spring-message–xx包 commons-collection-xx包 commons-pool2-xx包 aop切面的包: spring-aop,spring-aspect... Sprng-jms消息服务小项目 所需的包: spring的基础包 spring-jms-xx包 spring-message–xx包 commons-collection-xx包 c

Spring-boot JMS 发送消息慢的问题解决

1:在<ActiveMQ 基于zookeeper的主从(levelDB Master/Slave)搭建以及Spring-boot下使用>(http://www.cnblogs.com/yshyee/p/7277801.html)中,采用以下代码进行JMS消息发送: @Service public class Producer { @Autowired private JmsMessagingTemplate jmsTemplate; public void sendMessage(Destin

Spring整合JMS(二)——消息监听器

消息监听器 在Spring整合JMS的应用中我们在定义消息监听器的时候一共能够定义三种类型的消息监听器,各自是MessageListener.SessionAwareMessageListener和MessageListenerAdapter. 以下就分别来介绍一下这几种类型的差别. MessageListener MessageListener是最原始的消息监听器.它是JMS规范中定义的一个接口.当中定义了一个用于处理接收到的消息的onMessage方法,该方法仅仅接收一个Message參数.

ActiveMQ实例2--Spring JMS发送消息

参考文章:http://my.oschina.net/xiaoxishan/blog/381209#OSC_h3_7 一,步骤参照参考文献 二.新建的项目 三.补充 web.xml 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 3 xmlns

ActiveMQ学习笔记(五)——使用Spring JMS收发消息

ActiveMQ学习笔记(四)http://my.oschina.net/xiaoxishan/blog/380446 中记录了如何使用原生的方式从ActiveMQ中收发消息.可以看出,每次收发消息都要写许多重复的代码,Spring 为我们提供了更为方便的方式,这就是Spring JMS.我们通过一个例子展开讲述.包括队列.主题消息的收发相关的Spring配置.代码.测试. 本例中,消息的收发都写在了一个工程里. 1.使用maven管理依赖包 <dependencies> <depend