Kafka提升——接收-处理-发送事务

接收-处理-发送事务

在消费者接收到数据后,对数据进行处理,然后进行发送到队列。

例如:
用户注册成功后,获得注册优惠券。

当用户注册成功后,需要向用户表插入数据。同时需要向优惠券表插入新的优惠券信息。若在单体应用中,事务的实现非常容易实现,但是在分布式的服务中,事务的实现就需要进行研究了。

分布式的事务暂时不表,此处就讨论消息队列如何完成这里的实现。

假设,目前有用户服务A,优惠券服务B,通过消息队列进行消息传递。

当用户注册时,首先向A发送消息,完成用户的注册表的插入。然后向B发送信息,通知插入优惠券信息。(loger 代替数据库插入,肯定满足事务,不需要多考虑)

    @KafkaListener(topics = "registry", containerFactory = "stringKafkaListenerContainerFactory2")
    @KafkaListener(topics = "youhuiquanhuidiao", containerFactory = "stringKafkaListenerContainerFactory2")
    @Transactional
    public void receiveStringRegistry(String message,
                                      @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
        if("youhuiquanhuidiao".equals(topic)){
            logger.info("优惠券给他了已经!!");
        }else {
                logger.info("收到用户信息:"+message);
                logger.info("用户信息插入");
                logger.info("用户信息插入完成");
                transactionalTemplate.send("youhuiquan","新注册用户,给他个优惠券!");
        }
    }
    

B收到消息后,对优惠券信息进行插入,插入完成后,发送信息回调再做另外处理。

    
    @KafkaListener(topics = "youhuiquan", containerFactory = "stringKafkaListenerContainerFactory2")
    @Transactional
    public void receiveStringYouhuiquan(String message,
                                        @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
        try{
            logger.info("收到信息:"+message);

            logger.info("优惠券插入");

            logger.info("优惠券插入完成");

            int i = 1/0;

            transactionalTemplate.send("youhuiquanhuidiao","优惠券给他了已经!!");
        }catch (Exception e){
            transactionalTemplate.send("youhuiquanhuidiao","发生错误了,优惠券没给成!");
        }
    }

controller

    @RequestMapping("/testSendMsg4")
    @ResponseBody
    @Transactional
    //@KafkaListener(topics = "topic1", containerFactory = "stringKafkaListenerContainerFactory2")
    public String testSendMsg5(){ //事务发送
        Message message = new Message();
        message.setId(1);
        message.setMsg("我是小明,我来注册");
        message.setSendTime(new Date());
        logger.info("发送消息(事务发送) ----->>>>>  message = {}", gson.toJson(message));
        transactionalTemplate.send("registry", gson.toJson(message)).addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
            @Override
            public void onFailure(Throwable throwable) {
                logger.error("发生错误,消息发送失败!");
            }

            @Override
            public void onSuccess(SendResult<String, String> stringStringSendResult) {
                logger.info("消息发送成功!");
            }
        });
        //int i = 1/0;
        return "testSendMsg5";
    }

1550092-20200318172016762-1540729861.png

1550092-20200318172039256-324398937.png

现在 我们把业务系统想的复杂一些,用户注册完成后还需要进行其他方面的操作,也就是需要向其他服务发出信息。此时若一个发生错误,其他都不在发送(发送错误的处理先不表,可以看下后续的分布式事务的处理。)

1550092-20200318172051221-640258660.png

可以看到,添加事务后,发生错误后全都不在进行发送。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值