java redis做app后台 怎么实现多人抢单

java jfinal和redis作为后台。

具体流程是:


app端:

app有信息展示,用户选择一条信息进入详细,然后点击抢单按钮,这时携带2个id参数发送给后台


后台:

根据2个id,修改订单表的状态和用户的接单数


现在考虑高并发的问题,该怎么使用redis的队列呢?


我试过使用redis 在创建订单时把订单id存入redis


@ActionKey("/order/create")

    public void order_create(){


        Order order = Order.dao.order_create(map);

        JSONObject jsonObject = new JSONObject();

        jsonObject.put("rs", order.result);

        jsonObject.put("msg", StateDict.dataBaseMsg(order.result));


        Cache c = Redis.use("order");

        c.rpush("orderlist", order.id);

        renderJson(jsonObject);


    }

然后在app点击抢单按钮时读取redis


@ActionKey("/order/take")

    public void order_take(){

        Integer id = getParaToInt(0);

        Integer uid = getParaToInt(1);

        

        Cache orderCache = Redis.use("order");

        Object orderlist = orderCache.lpop("orderlist");

        

        JSONObject json = new JSONObject();


        if(orderlist!=null){

            int rs = Order.dao.order_take(id,uid);

            json.put("rs", rs);

            json.put("msg", StateDict.dataBaseMsg(rs));

        }else{

            int rs = StateDict.ORDER_TAKEN;

            json.put("rs", rs);

            json.put("msg", StateDict.dataBaseMsg(rs));

        }


        renderJson(json);

    }

但是我模拟多并发时,同一个用户可以接多次单,也就是用户的接单数不是1次而是多次,

求高手看看 我该怎么写,

我对redis也不是太熟 刚开始使用


这时操作数据库的代码


public int order_take(int id,int uid){

        

            int state = Db.queryInt("SELECT t.state FROM t_order t WHERE t.id=?", id);

            //多个请求同时进来的时候state都是0,所以都会进入if条件

            if(state==0){

                int rs1 = Db.update("UPDATE t_order SET taketime=?,takeuserid=?,state=? WHERE id=?", User.dao.getSysTime(),uid,1,id);

                if(rs1>0){

                    int rs2 = Db.update("UPDATE t_user SET takecount=takecount+1 WHERE id=?",uid);

                    if(rs2>0){

                        return StateDict.DATABASE_SUCCESS;

                    }else{

                        return StateDict.DATABASE_FAIL;

                    }

                }else{



慕雪6442864
浏览 903回答 1
1回答

慕码人2483693

没太看懂你的代码表达的意思,感觉跟你的描述不太相符。用redis也不是不可以,但效率可能有点低,建议使用乐观锁解决这个问题。举个例子:假设order表里有个version字段,该字段只能单向自增(一般就是+1),SELECT的时候把version也查出来:SELECT ..., version FROM order WHERE ...;UPDATE orderSET ...,version = version+1WHERE version = 上一个SELECT语句带出来的version值假设用户A和用户B在某时间段内先后或同时查出来order_id=1, version=1的订单,UPDATE的时候由于mysql行锁的存在,只会有一个用户UPDATE成功(1 rows affected),另一个用户则UPDATE失败(0 rows affected),然后可以根据UPDATE后返回的话行数判断用户是否抢单成功。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java