以redis方案为例
Consumer收到一条massageA(messageId = a),这个时候我做以下操作保障幂等性:
1、setnx(messageId,expireTime),成功表示redis中没有该消息,处理相关逻辑,失败表示redis中有该消息,已处理或者正在处理该消息。
2、如果出现setnx成功,但是实际业务处理失败的场景,这时候,需要做两件事,(a)redis中delete这个key(messsageId),(b)不发送confirm回MQ
3、由于MQ长时间未收到confirm,回重试,重新开始步骤1
*步骤二中,所谓的业务处理失败,是指比方说数据写入失败,或者rpc调用失败等重试后可成功处理的失败,并非业务实际逻辑的失败,比方说超买超卖等,这类无法重试成功的错误,应该时要依靠分布式事务由producer端自己补偿的
所以,我的问题是,我不理解为什么要持久化消息,或者说我认为幂等性是指,出现重复消息时我怎么解决,比方说,一个用户发了一次购买请求,但是MQ由于网络啊或者其他原因重复发送了多次,我consumer应该要做到一个massgeId只处理一次;而不是说我用户发了10次购买请求,但是我只能处理9次,因为第10次就超卖了,这种情况是事务级别的问题,不是幂等的问题
换句话说,我觉的幂等性,只需要持久化这条消息的唯一标识,而不用持久化整条消息,所以持久化消息唯一标识时,可以存在关系型数据库,也可以存在no-sql数据库中,但是并没有即存在redis又同步到数据库的意义。