prontera / spring-cloud-rest-tcc

以Spring Cloud Netflix作为服务治理基础, 展示基于tcc思想所实现的分布式事务解决方案
2.58k stars 1.21k forks source link

IncreasePointsEventHandler类中如果消费失败了,没有回执消息,mq中的消息还是会被消费掉 #45

Closed ljh205sy closed 4 years ago

ljh205sy commented 6 years ago

真正的消费业务逻辑在IncreasePointsEventHandler中,如果try中自己的业务抛出了异常,改如何处理?

@Override public void handle(EventSubscriber subscriber) { Preconditions.checkNotNull(subscriber); Preconditions.checkNotNull(subscriber.getId()); try { if (Objects.equal(BUSINESS_TYPE, subscriber.getBusinessType())) { // 这里取巧,将生产者的报文特地写成PointFlow的格式 final PointFlow request = Jacksons.getMapper().readValue(subscriber.getPayload(), PointFlow.class); // 简单地增加流水,为了简便就没有模拟任何业务上的校验 pointService.persistFlow(request); // 增加总数 pointService.increasePoint(request.getPoint(), request.getUserId()); getMapper().updateEventStatusByPrimaryKeyInCasMode(subscriber.getId(), EventStatus.NEW, EventStatus.DONE); } else { if (successor != null) { successor.handle(subscriber); } }

    } catch (IOException e) {
        throw new IllegalArgumentException("读取JSON报文至实体时发生异常. payload: " + subscriber.getPayload() + ", entity: PointFlow.class");
    }
}
prontera commented 4 years ago

如果在try中的逻辑出现问题,实质上是属于BUG,作为业务方的我们应该保证不会这种问题,但真要出现,为了避免误消费消息,不能向RabbitMQ响应ACK。

另外本项目回归主题rest-tcc,相关模块已全部重写,精简无关组件,并详细补充tcc实现细则,感谢关注,有问题可re-open或继续在GitHub Issue中交流!