Skip to content

是否存在情况当未在指定时间段内收到ACK返回,但Redis却被处理的情况(handleInRedis方法正常执行),导致redis库存数-1的情况 #19

@WXzhongwang

Description

@WXzhongwang

是否存在情况当未在指定时间段内收到ACK返回,

    boolean sendAcked = false;
        try {
            sendAcked = channel.waitForConfirms(100);  100ms时间内
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }

但Redis却被处理的情况(handleInRedis方法正常执行),

 @Override
    public void handleInRedis(long seckillId, long userPhone) throws SeckillException {
        Jedis jedis = jedisPool.getResource();

        String inventoryKey = RedisKeyPrefix.SECKILL_INVENTORY + seckillId;
        String boughtKey = RedisKeyPrefix.BOUGHT_USERS + seckillId;

        String inventoryStr = jedis.get(inventoryKey);
        int inventory = Integer.valueOf(inventoryStr);
        if (inventory <= 0) {
            logger.info("handleInRedis SECKILLSOLD_OUT. seckillId={},userPhone={}", seckillId, userPhone);
            throw new SeckillException(SeckillStateEnum.SOLD_OUT);
        }
        if (jedis.sismember(boughtKey, String.valueOf(userPhone))) {
            logger.info("handleInRedis SECKILL_REPEATED. seckillId={},userPhone={}", seckillId, userPhone);
            throw new SeckillException(SeckillStateEnum.REPEAT_KILL);
        }
        jedis.decr(inventoryKey);
        jedis.sadd(boughtKey, String.valueOf(userPhone));
        logger.info("handleInRedis_done");
    }

导致redis库存数-1,且用户无法继续购买的问题

12/17-17:18:54 [http-nio-27000-exec-2] INFO  com.liushaoming.jseckill.backend.mq.MQProducer-  [mqSend] '{"seckillId":1000,"userPhone":18668042850}'
12/17-17:18:54 [pool-3-thread-6] INFO  com.liushaoming.jseckill.backend.mq.MQConsumer- ---receive_threadId_1=42
12/17-17:18:54 [pool-3-thread-6] INFO  com.liushaoming.jseckill.backend.mq.MQConsumer- [mqReceive]  '{"seckillId":1000,"userPhone":18668042850}'
12/17-17:18:54 [pool-3-thread-6] INFO  com.liushaoming.jseckill.backend.service.impl.SeckillServiceImpl- handleInRedis_done
12/17-17:18:54 [pool-3-thread-6] INFO  com.liushaoming.jseckill.backend.mq.MQConsumer- ------processIt----
12/17-17:18:54 [pool-3-thread-6] INFO  com.liushaoming.jseckill.backend.mq.MQConsumer- ---->ACK
java.util.concurrent.TimeoutException
	at com.rabbitmq.client.impl.ChannelN.waitForConfirms(ChannelN.java:229)
	at com.rabbitmq.client.impl.recovery.AutorecoveringChannel.waitForConfirms(AutorecoveringChannel.java:697)
	at com.liushaoming.jseckill.backend.mq.MQProducer.send(MQProducer.java:53)
	at com.liushaoming.jseckill.backend.service.impl.SeckillServiceImpl.handleSeckillAsync(SeckillServiceImpl.java:172)
	at com.liushaoming.jseckill.backend.service.impl.SeckillServiceImpl.executeSeckill(SeckillServiceImpl.java:124)
	at com.liushaoming.jseckill.backend.service.impl.SeckillServiceImpl$$FastClassBySpringCGLIB$$85f44643.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684)
	at com.liushaoming.jseckill.backend.service.impl.SeckillServiceImpl$$EnhancerBySpringCGLIB$$4cd4b877.executeSeckill(<generated>)
	at com.liushaoming.jseckill.backend.controller.SeckillController.execute(SeckillController.java:90)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)
12/17-17:18:54 [http-nio-27000-exec-2] INFO  com.liushaoming.jseckill.backend.mq.MQProducer- sendAcked=false
12/17-17:18:54 [http-nio-27000-exec-2] INFO  com.liushaoming.jseckill.backend.mq.MQProducer- !!!mqSend_NACKED,NOW_RETRY>>>
12/17-17:18:54 [http-nio-27000-exec-2] INFO  com.liushaoming.jseckill.backend.service.impl.SeckillServiceImpl- ENQUEUE_PRE_SECKILL>>>seckillId=1000,userPhone=18668042850
12/17-17:18:54 [pool-3-thread-3] INFO  com.liushaoming.jseckill.backend.mq.MQConsumer- ---receive_threadId_1=38
12/17-17:18:54 [pool-3-thread-3] INFO  com.liushaoming.jseckill.backend.mq.MQConsumer- [mqReceive]  '{"seckillId":1000,"userPhone":18668042850}'
12/17-17:18:54 [pool-3-thread-3] INFO  com.liushaoming.jseckill.backend.service.impl.SeckillServiceImpl- handleInRedis SECKILL_REPEATED. seckillId=1000,userPhone=18668042850
12/17-17:18:54 [pool-3-thread-3] INFO  com.liushaoming.jseckill.backend.mq.MQConsumer- ------processIt----
12/17-17:18:54 [pool-3-thread-3] INFO  com.liushaoming.jseckill.backend.mq.MQConsumer- --LET_MQ_ACK REASON:SeckillStateEnum.SOLD_OUT,SeckillStateEnum.REPEAT_KILL

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions