JMS消息确认模式

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhanglh046/article/details/78697447

JMS消息只有在被确认之后,才认为已经成功的被消费了。消息的成功消费通常包含三个阶段:客户接收消息,客户处理消息和消息被确认。

 

一 事务性会话

在事务性会话中,当一个事务被提交的时候,确认自动发生;即只需设置Session.SESSION_TRANSACTED。

一般而言,在创建事务性Session的时候:

Connection.createSession(是否支持事务,应答模式)

如果第一个参数设置为true,即事务性会话,那么不需要显示设置第二个参数: 应答模式.

Session.SESSION_TRANSACTED,因为创建会话的第一个参数设置为true,就代表着应答模式为Session.SESSION_TRANSACTED,而且第二个参数也没有意义,可以忽略此参数,比如你设置成了AUTO_ACKNOWLEDGE,对于会话来说没有任何意义,因为会被忽略。

如何提交会话?

Session.commit();

测试:

产生消息:

public class MessageSender {
    public staticvoid main(String[] args) throws JMSException {
        ConnectionFactoryconnectionFactory = new ActiveMQConnectionFactory("tcp://192.168.3.200:61616");
        Connection connection = connectionFactory.createConnection();
        connection.start();
        Session session = connection.createSession(Boolean.TRUE, Session.SESSION_TRANSACTED);
        Destination dest = session.createQueue("animals");
        MessageProducerproducer = session.createProducer(dest);
        MapMessage message = null;
        for (int i = 1; i <= 6; i++) {
            message = session.createMapMessage();
            message.setIntProperty("ackCode", Session.CLIENT_ACKNOWLEDGE);
            message.setString("MSG---" + i, "Product ID---"+i);
            producer.send(message);
        }
        session.close();
        connection.close();
    }
}

我们并没有提交消息,那么我们查看是否产生了6条消息


如果我们调用Session,commit();结果呢?这下肯定就有了。



二 非事务性会话

在非事务性会话中,消息何时被确认取决于创建会话的应答模式---

acknowledgement

 

Acknowledgement模式有三个可选值:

# AUTO_ACKNOWLEDGE

当客户端成功接受到消息,就会自动确认收到消息,比如receive方法或者MessageListener.onMessage方法,这方式就是一条消息确认一次。

public class MessageReciver {
    public static void main(String[] args) throws JMSException {
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.3.201:61616");
        Connection connection = connectionFactory.createConnection();
        connection.start();
        Session session = connection.createSession(Boolean.FALSE,Session.AUTO_ACKNOWLEDGE);
        Destination destination = session.createQueue("animals");
        MessageConsumer consumer = session.createConsumer(destination);
        int i = 0;
        MapMessage message = null;
        while (i < 6) {
            i++;
            message = (MapMessage) consumer.receive();
            System.out.println("消息: "+message.getString("MSG---" + i));
        }
        session.close();
        connection.close();
    }
}

 

# CLIENT_ACKNOWLEDGE

客户端必须通过Message明确调用acknowledge方法确认收到消息

public class MessageReciver {
    public static void main(String[] args) throws JMSException {
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.3.201:61616");
        Connection connection = connectionFactory.createConnection();
        connection.start();
        Session session = connection.createSession(Boolean.FALSE,Session.CLIENT_ACKNOWLEDGE);
        Destination destination = session.createQueue("animals");
        MessageConsumer consumer = session.createConsumer(destination);
        int i = 0;
        MapMessage message = null;
        while (i < 6) {
            i++;
            message = (MapMessage) consumer.receive();
            System.out.println("消息: "+message.getString("MSG---" + i));
            message.acknowledge();
        }
        session.close();
        connection.close();
    }
}

 

# DUPS_OK_ACKNOWLEDGE

延迟确认提交,可能存在重复的提交。比如客户端接受了10条消息,并且已经处理了,但是因为延迟提交了,所以JMS服务端可能还没有确认。这时候假设JMS 服务器宕机,那么重启之后,可能会因为之前没有提交的消息会进行重新发送,就导致重复发送的问题。

一般重新发送会设置一个消息头:JMSRedelivered设置为true


展开阅读全文

没有更多推荐了,返回首页