我们在创建session的时候,往往有两个参数要填,第一个为事务transation参数(true/false),true表示使用事务,false表示不使用事务,第二个参数为接收,后面再讲,先学习事务基本用法,即参数使用true,这时,当我们发送完数据,需要释放资源时,在session资源释放之前需要commit提交事务,否则发送的数据服务器不予响应,消费者端同理,消费完消息之后也需要在session关闭前commit提交事务,否则消费者会重复消费数据。
生产者:
ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(ACTIVEMQ_URL);
//create connect and start
Connection connection=activeMQConnectionFactory.createConnection();
connection.start();
//create session
Session session = connection.createSession(true, AUTO_ACKNOWLEDGE);
//create 目的地
Queue queue=session.createQueue(Queuep);
//create producer
MessageProducer messageProducer=session.createProducer(queue);
// messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
//send massege
for(int i=0;i<6;i++){
//create message
TextMessage textMessage=session.createTextMessage("message---"+i);
messageProducer.send(textMessage);
textMessage.setStringProperty("kehu","vip");
}
messageProducer.close();
session.commit();
session.close();
connection.close();
System.out.println("消息发送完毕");
这里代码不全,和之前的一样的,只是改了一点点内容。这里我们不妨测试一下,将session.commit()注释掉,执行代码向服务器发送消息,会出现:
会发现有名为queue01的队列没有消息(将之前的测试删除再测试这个代码)然后将注释去掉,使用commit提交事务
可以看到队列里面有消息在等待了。我们再看消费者:
ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(ACTIVEMQ_URL);
//2.create connect and start
Connection connection=activeMQConnectionFactory.createConnection();
connection.start();
//3.create session
Session session = connection.createSession(true, AUTO_ACKNOWLEDGE);
//4.create 目的地
Queue queue=session.createQueue(Queuep);
//5.create consumer
MessageConsumer messageConsumer=session.createConsumer(queue);
while (true){
//6.监听并获取消息
TextMessage message =(TextMessage) messageConsumer.receive(1000);
if(null!=message){
System.out.println("消费者消费消息:"+message.getText());
}else {
break;
}
}
//7.关闭资源
messageConsumer.close();
session.commit();
session.close();
connection.close();
同理,我们先测试一下注释commit,运行之后结果队列内容没变,有一个消费者
这时应为我们没有提交commit,所以事务仅仅执行了而没有提交执行结果(术语讲不来,只能说土话哈哈)
去掉注释,执行
第二部分:签收
activemq的签收机制acknowledge有四个参数:AUTO_ACKNOWLEDGE,CLIENT_ACKNOWLEDGE,DUPA_OK_ACKNOWLEDGE,SESSION_TRANSACTED
(1)AUTO_ACKNOWLEDGE 为默认签收模式,即消费者消费到消息则自动签收,服务器端显示为已消费,其他消费者不能再消费
(2)CLIENT_ACKNOWLEDGE 为手动签收模式,即消费者消费消息之后需要手动签收代码textMessage.acknowledge();完成签收,才表示消息已经被消费,示例(签收机制偏消费者,生产者参数改一下就好了,示例为非事务环境,若环境为事务环境,则没有手动签收也会被commit默认签收,但是若没有commit,手动签收也无法签收,因为事务才是最小操作单元):
package com.xiaowu.activemq;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import static javax.jms.Session.AUTO_ACKNOWLEDGE;
import static javax.jms.Session.CLIENT_ACKNOWLEDGE;
public class JmsConsumer {
public static final String ACTIVEMQ_URL="tcp://152.136.12.27:61616";
public static final String Queuep="queue01";
public static void main(String[] args) throws JMSException {
//1.create factory
ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(ACTIVEMQ_URL);
//2.create connect and start
Connection connection=activeMQConnectionFactory.createConnection();
connection.start();
//3.create session
Session session = connection.createSession(false, CLIENT_ACKNOWLEDGE);
//4.create 目的地
Queue queue=session.createQueue(Queuep);
//5.create consumer
MessageConsumer messageConsumer=session.createConsumer(queue);
while (true)
{
//6.监听并获取消息
TextMessage textMessage =(TextMessage) messageConsumer.receive(1000);
if(null!=textMessage){
System.out.println("消费者消费消息:"+textMessage.getText());
//手动签收
textMessage.acknowledge();
}else {
break;
}
}
//7.关闭资源
messageConsumer.close();
// session.commit();
session.close();
connection.close();
}
}
运行结果图就不贴了,和之前没什么差距
(3)DUPA_OK_ACKNOWLEDGE 带副本的允许重复消费的消息,即在签收之前其他消费者可以同时消费,视频老师没讲说不重要,这个留着以后遇到再说。
(4)SESSION_TRANSACTED 老师啥也没讲。。。那就这样吧@_@