ActiveMQ生产者和消费者事务_9

一、生产者事务

创建session的时候,我们传了两个参数,第一个是事务,第二个是签收,我们来说说事务。

Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

方法的第一个参数就是事务,它的值可以是true或false,代表session的提交是事务提交还是非事务提交。

当事务的值是false时,只要执行了messageProducer.send()方法,消息就到了队列中,也就是自动提交了。

当事务的值是true时,在执行完messageProducer.send()方法后,在session关闭之前需要多加一个session.commit()方法提交事务。

事务的提交,用于实际复杂的业务场景,可能有多个消息需要入队列,假设有一条入队列报错了,我希望这一批次的都要回滚,这就要提到session.rollback();方法了,可以将session.rollback();方法放在catch语句块中来执行。

代码

public class JmsProduce_TX {

    public static final String ACTIVEMQ_URL = "tcp://10.5.96.48:61616";
    public static final String  QUEUE_NAME = "queue-atguigu";

    public static void main(String[] args) throws JMSException {
        //1.创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //2.通过 连接工厂,获得连接connection并启动访问
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();
        //3.创建会话session
        //两个参数 ,第一个叫事务,第二个叫签收
        Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
        //4 .创建目的地
        Queue queue = session.createQueue(QUEUE_NAME);
        //5.创建消息生产者
        MessageProducer messageProducer = session.createProducer(queue);
        // 6.通过使用messageProduce生产3条消息发送到MQ队列里面
        for (int i = 0; i < 3; i++) {
            //7.创建消息
            TextMessage textMessage = session.createTextMessage("tx msg --- " + i);
            //8 .通过messageProducer发送给mq
            messageProducer.send(textMessage);
        }
        //9.关闭资源
        messageProducer.close();
       /**如果上面connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
         *  1.如果是true 这里需要session.commit()先提交事务,在关闭session ,否则队列中没有 
              消息
         *  2.如果是false ,可以不用提交,会自动提交
         */
        session.close();
        connection.close();
        System.out.println("********tx消息发布到MQ完成");

        try {
            //如果是批量 消息 ok session.commit();
        }catch (Exception e){
            e.printStackTrace();
            session.rollback(); //事务回滚 要么都成功 要么都失败
        }finally {
            if(null!=session){
                session.close(); //关闭session
            }
        }
    }
}

如果session的第一个参数设置的是true ,没有session.commit();队列如图没有收到消息。

如果是false 可以自动接受到消息 

二、消费者事务

事务主要是针对生产者而言的,但是对于消费者,也有事务。

将connection.createSession()的第一个参数改为true,表示消费者消费采用事务的方式,如果开启了事务,就需要手动执行session.commit();来提交事务,假设这时候,我们不提交事务,看看会出现什么情况。

先启动生产者,后启动消费者,控制台可以看到消费者消费了消息,但是我们没有执行commit();方法,再次执行消费者,发现又做了一次消费,也就是说,消费者的消费行为没有提交,也就没有通知到MQ,MQ认为消息还没有被消费,所以会出现重复消费的情况。

对于事务,一般情况下就用false即可,如果此时需要保证事务的一致性,那么就要使用true,另外一定不要忘了session.commit();手动提交,否则会出现比较麻烦的问题。
 

public class JmsConsumer_TX {

    public static final String ACTIVEMQ_URL = "tcp://10.5.96.48:61616";
    public static final String  QUEUE_NAME = "queue-atguigu";

    public static void main(String[] args) throws JMSException {
        //1.创建连接工厂,按照给定的url地址,采用默认的用户名和密码
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //2.通过链接工厂,获得连接connection并启动访问
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();
        //3.创建会话
        Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
        //4.创建目的地
        Queue queue = session.createQueue(QUEUE_NAME);
        //5.创建消费者
        MessageConsumer messageConsumer = session.createConsumer(queue);
        while (true)
        {
            TextMessage textMessage = (TextMessage) messageConsumer.receive(4000);
            if(null != textMessage){
                System.out.println("********消费者接收消息:"+ textMessage.getText());
            }else{
                break;
            }
        }
        messageConsumer.close();
        /** 如果消费者Session session = 
            connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
         * 1.如果设置的是false 消费了消息的话,就不会重复消费
         * 2.如果是true 。必须session.commit()否则会出现重复消费的情况
         */
        session.close();
        connection.close();
    }
}

参考

  https://blog.csdn.net/qq_36059561/article/details/103812438

  https://blog.csdn.net/qq_36059561/article/details/103812598 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值