• 黑马点评用rabbitmq实现优惠券秒杀下单后的异步操作数据库数据


    导入配置

    		<dependency>		
    			<groupId>org.springframework.bootgroupId>
    			<artifactId>spring-boot-starter-amqpartifactId>
    			<version>2.7.7version>
    		dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    配置文件配置

    在这里插入图片描述

    JavaConfig配置

    @Component
    @Slf4j
    public class RabbitmqConfig implements InitializingBean {
        @Resource
        private RabbitTemplate rabbitTemplate;
    
        @Override
        public void afterPropertiesSet() throws Exception {
            log.info("初始化配置rabbitmq配置");
    
    //        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter(new ObjectMapper()));
            rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
                @Override
                public void confirm(CorrelationData correlationData, boolean b, String s) {
                    if(!b)
                    {
                        log.error("发送消息到mq失败,原因:{}",s);
                    }
                }
            });
            rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
                @Override
                public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                    log.error("消息返回回调触发,交换机:{},路由:{},消息内容:{},原因:{}",exchange,routingKey,message,replyText);
                }
            });
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    通过@Bean注入MessageConverter,保证消息的正确传输

        @Bean
        public MessageConverter jsonMessageConverter(ObjectMapper objectMapper) {
            return new Jackson2JsonMessageConverter(objectMapper);
        }
    
    • 1
    • 2
    • 3
    • 4

    修改后的代码

        @Override
        //关于事务注解
        public Result seckillVoucher(Long voucherId) {
    //        1,执行lua脚本,lua脚本用于判断库存是否充足,扣库存操作
            Long userId=UserHolder.getUser().getId();
            long orderId=redisIDworker.nextId("order");
    
            //执行此操作前保证,用户查看优惠券的请求,和添加优惠券时 已经将秒杀优惠圈的库存数量添加到了redis中
            Long result=stringRedisTemplate.execute(
                    SECKILL_SCRIPT,
                    Collections.emptyList(),
                    voucherId.toString(),
                    userId.toString(),
                    String.valueOf(orderId)
            );
            //获取lua脚本返回值
            int r=result.intValue();
            if(r!=0)
            {
                return Result.fail(r==1?"库存不足":"不能重复下单");
            }
    //        //获取代理对象
    //        IVoucherOrderService proxy= (IVoucherOrderService) AopContext.currentProxy();
            //异步写数据库
            VoucherOrder voucherOrder = new VoucherOrder();
            voucherOrder.setId(orderId);
            voucherOrder.setUserId(userId);
            voucherOrder.setVoucherId(voucherId);
            rabbitTemplate.convertAndSend(SaveVoucherConstants.SECKILL_VOUCHER_SAVE_QUEUE,voucherOrder);
            log.info("发送保存秒杀券订单信息成功:{}",orderId);
            return Result.ok("seckSuccess");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    监听器

    @Component
    @Slf4j
    public class AsyncSaveVoucherListener {
        @Resource
        private IVoucherOrderService voucherOrderService;
        @Resource
        private ISeckillVoucherService seckillVoucherService;
        @RabbitListener(queuesToDeclare = {@Queue(name= SaveVoucherConstants.SECKILL_VOUCHER_SAVE_QUEUE)})
        public void AsyncSave(VoucherOrder voucherOrder)
        {
            log.info("接收到存储订单信息的消息,{}", JSON.toJSON(voucherOrder).toString());
            boolean success = seckillVoucherService.update().setSql("stock=stock-1").eq("voucher_id", voucherOrder.getVoucherId()).gt("stock", 0).update();
            voucherOrderService.save(voucherOrder);
            log.info("订单信息存储完成?{}",success);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    LeetCode 740.删除并获得点数---->打家劫舍
    TypeScript核心篇——类(class)-可选参数-存取器-构造函数-静态属性方法-抽象类
    初级算法_字符串 --- 字符串中的第一个唯一字符
    微服务和领域驱动
    定时任务 Quartz
    6 面向对象
    Linux结构目录说明以及相关作用【重点】
    leetcode二叉树系列(二)
    D. Reverse Sort Sum(思维 + 差分 + 树状数组)
    11.21 - 每日一题 - 408
  • 原文地址:https://blog.csdn.net/qq_51050526/article/details/134448473