一、幂等性处理方式
1、使用唯一id
生产者和消费者都需要添加配置类:
@Beanpublic MessageConverter jsonMessageConverter() {Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();jackson2JsonMessageConverter.setCreateMessageIds(true);return jackson2JsonMessageConverter;}
消费者拿到id之后,保存到数据库,后续消费时,需要查数据库进行比较,因此这种方案的缺点就是有业务的入侵,对性有一定的影响。
2、业务的幂等性
(1)查询和删除操作本身就是幂等性操作。
(2)可以使用分布式锁,对单据id锁定,防止多次提交,但是需要设置过去时间,只是避免短期重复提交,后续单据可能退回。
3、案例优化
案例:订单支付完成之后需要修改订单状态,此时需要通过支付服务调用订单服务修改订单状态。
解决:可以在订单服务中增加一个对订单状态的判断,如果订单状态不为未支付,则不能改动订单的状态,大概逻辑如下:
- 查询订单信息
- 判断订单状态
- 修改订单状态
这个案例比较特殊,是典型的比较交换逻辑,属于乐观锁,因此可以优化成为一个sql:
update order set oderStatus = 2 where id = ? and oderStatus = 1
当状态为1时才去修改为2,完美~