第八章 事务型消息

问题:关于消息队列的事物问题

spring的@Transactional标签只有当整个方法执行完成后才commit,这样如果因为网络问题即使整个方法执行成功,方法中消息队列发送成功,但是commit时失败了,减库存的rocketmq无法回滚。

解决方法1:spring @Transactional提供在事务提交成功后再执行某些方法的能力

在创建好订单入库后,最后执行异步更新库存

    // 在最近的一个@Transactional提交成功后才会执行
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
        	@Override
        	public void afterCommit() {
        	  // 4.异步同步库存
                  boolean mqResult = itemService.asyncDecreaseStock(itemId, amount);
            // 发送失败可能是没收到返回的确认消息,实际已经同步成功了   if(!mqResult) { itemService.increaseStock(itemId, amount); //throw new BusinessException(EmBusinessError.SEND_ROKETMQ_FAIL);   } } });

  

方法1的问题是,当异步消息发送失败后就没办法回滚了,失败就永远丢失了该消息,但是订单已经创建造成超卖,所以考虑事务型rocketmq

解决方法2:transaction rocketmq

redis不可用时,如何操作?

使用数据库数据来扣减,可是如何确定异步同步消息已经都消费了,否则实际数据库库存会比正常多。

一般只能少卖不能多卖。程序block,运维来恢复

超时释放的问题

出现大面积假死,redis已经被减了,但是订单没有成功,后台需要回滚十五分钟,将redis加上去

猜你喜欢

转载自www.cnblogs.com/t96fxi/p/12093945.html