1、persistent:持久性
2、事务
3、Acknowledge:签收
非持久化,宕机后再重启就都是0了,消息不存在
持久化后,宕机重启消息都在,只不过没有入队,如图所示本来是3030,现在是3000
队列默认的是持久化。topic持久化需要消费者先订阅
topic一定要先运行一次消费者,等于向MQ注册,类似订阅了这个主题
然后再运行生产者发送消息,此时无论消费者额是否在线,都会接受到,不在线的话,下次连接的时候,会把没有收过的消息都接收。
这是事务创建时候的源代码:当transacted == true的时候,是不走if判断的,直接return ,return里的是三元表达式 transacted?==true的时候无论代码里签收方式是啥样的,最后的签收方式都是session_transacted
事务的话
假如生产者设置为false,那么只要执行send方法,消息就进入到队列中。----------------消费者事务设置为false,mq里的消息被消费------------------------------------------ 消费者事务设置为true,消费者显示是消费了消息,mq里的消息不被消费,但是------------消费者事务只有设置为true,并且commit的时候,mq里的消息才被消费掉,
假如生产者事务设置为true,那么执行完send方法,需要执行commit()消息才被真正的提交到队列中。----------------------------------------------------------------------------消费者事务设置为false,mq里的消息只能被消费一次。-----------------------------------消费者事务设置为true,消费者显示是消费了消息,但是mq里的消息没有变,显示没有被消费。只有消费者设置为true的同时commit了,mq里的消息才正确的被消费
生产者需要开启事务,并且最后要session.commit(),异常rollback,finally session.close()
很简单,就把mq想想成数据库,生产者往mq里发消息,那不就是insert么,insert肯定是要commit才能把消息提交到数据库(mq)里。不然mq里没有数据。
消费者这边也好理解,消费者事务是false的时候,是可以消费的,mq里消息也被消费掉。但是假如代码里有其他业务,还是设置成true好,设置成true,就必须commit。不然就是一直重复消费消息,mq里的消息不变
根本不用把生产者的事务和消费者的事务挂钩,生产者的事务是保证的是往mq里写数据的,是写进去了还是没写进去。
这个是事务的源码,可以看见假如生产者是开启了事务,那么签收方式最后都是 Session.SESSION_TRANSACTED
消息非事务模式下的签收。
自动签收是默认的,
手动签收,一定要调用ack才行,不然又是重复消费,mq里消息不变
消息在事务下的签收
如果事务为true了,那么后面的签收参数就不重要了,从源码中可以看出。但是一定要记得提交commit,ack不ack都行。如果事务为true,那么事务权限更大。事务为true,就是等于自动签收了。
网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。
加入交流群
请使用微信扫一扫!