首页 > 快讯 >

【Redis】-使用Lua脚本解决多线程下的超卖问题以及为什么?|天天新视野

2023-05-06 18:24:59 来源:博客园

一.多线程下引起的超卖问题呈现1.1.我先初始化库存数量为1、订单数量为0

1.2.开启3个线程去执行业务

业务为:判断如果说库存数量大于0,则库存减1,订单数量加1


【资料图】

结果为:库存为-2,订单数量为3

原因:如下图所示,这是因为分别有6个指令(3个库存减1指令,3个订单数量加1指令)在redis服务端执行导致的。

namespace MengLin.Shopping.Redis.LuaScript{    public class SecKillOriginal    {        static SecKillOriginal()        {            using (RedisClient client = new RedisClient("127.0.0.1", 6379))            {                //删除当前数据库中的所有Key, 默认删除的是db0                client.FlushDb();                //删除所有数据库中的key                 client.FlushAll();                //初始化库存数量为1和订单数量为0                client.Set("inventoryNum", 1);                client.Set("orderNum", 0);            }        }        public static void Show()        {            for (int i = 0; i < 3; i++)            {                Task.Run(() =>                {                    using (RedisClient client = new RedisClient("127.0.0.1", 6379))                    {                        int inventoryNum = client.Get("inventoryNum");                        //如果库存数量大于0                        if (inventoryNum > 0)                        {                            //给库存数量-1                            var inventoryNum2 = client.Decr("inventoryNum");                            Console.WriteLine($"给库存数量-1后的数量-inventoryNum: {inventoryNum2}");                            //给订单数量+1                            var orderNum = client.Incr("orderNum");                            Console.WriteLine($"给订单数量+1后的数量-orderNum: {orderNum}");                        }                        else                        {                            Console.WriteLine($"抢购失败: 原因是因为没有库存");                        }                    }                });            }        }    }}

二.使用Lua脚本解决多线程下超卖的问题以及为什么

2.1.修改后的代码如下

结果为:如下图所示,库存为0、订单数量为1,并没有出现超卖的问题且有2个线程抢不到。

namespace MengLin.Shopping.Redis.LuaScript{    public class SecKillLua    {        ///         /// 使用Lua脚本解决多线程下变卖的问题        ///         static SecKillLua()        {            using (RedisClient client = new RedisClient("127.0.0.1", 6379))            {                //删除当前数据库中的所有Key, 默认删除的是db0                client.FlushDb();                //删除所有数据库中的key                 client.FlushAll();                //初始化库存数量为1和订单数量为0                client.Set("inventoryNum", 1);                client.Set("orderNum", 0);            }        }        public static void Show()        {            for (int i = 0; i < 3; i++)            {                Task.Run(() =>                {                    using (RedisClient client = new RedisClient("127.0.0.1", 6379))                    {                        //如果库存数量大于0,则给库存数量-1,给订单数量+1                        var lua = @"local count = redis.call("get",KEYS[1])                                        if(tonumber(count)>0)                                        then                                            --return count                                            redis.call("INCR",ARGV[1])                                            return redis.call("DECR",KEYS[1])                                        else                                            return -99                                        end";                        Console.WriteLine(client.ExecLuaAsString(lua, keys: new[] { "inventoryNum" }, args: new[] { "orderNum" }));                    }                });            }        }    }}

三.为什么使用Lua脚本就能解决多线程下的超卖问题呢?

是因为Lua脚本把3个指令,分别是:判断库存数量是否大于0、库存减1、订单数量加1,这3个指令打包放在一起执行了且不能分割,相当于组装成了原子指令,所以避免了超卖问题。

在redis中我们尽量使用原子指令从而避免一些并发的问题。

上一篇:

动态焦点:贵州金沙:“中国制”自动售货机出口日本

下一篇:

最后一页

x
推荐阅读

【Redis】-使用Lua脚本解决多线程下的超卖问题以及为什么?|天天新视野

动态焦点:贵州金沙:“中国制”自动售货机出口日本

天天最新:疯传!深圳老牌地产中介倒闭?公司紧急回应

天天消息!1533红酒_1533

打好税收政策组合拳 护航小微企业健康发展 环球热消息

同级独有豪华轿车-林肯Z

2022年云南农村居民人均可支配收入达15147元

全球观点:redvelvet回归_red velvet回归

oem是什么意思啊_千寻一醉什么意思|速看

动态焦点:飞凡双旗舰舒适登场,遇见北京时尚新风景

全球快讯:孟加拉国国家足球队

“香港第一美女”钟楚红近况曝光:丈夫去世16年,63岁无儿无女,曾经的一代女神,如今活成了这样……|视点

商务部郑重声明:“世界汽车大会”与商务部无关

环球报道:诸葛亮借东风歇后语下一句_诸葛亮借东风

涉嫌严重违纪违法,黑河市原副市长张瑾忠被查

世界热门:萌化!上海老城厢被巨型猫咪“占领”了!

中超:武汉三镇平浙江|世界报道

全球速读:谷歌Pixel7a在谷歌正式发布之前出现在拆解视频中

中考分流不可怕,换个思路一样读大学,可怕的是被班主任“分流”

格力电器发布更正公告:董事长股份“质押”被误填为“冻结”|环球热文

意大利船级社与新加坡海事和港务局签署未来合作意向书

环球微头条丨国家邮政总局投诉热线区号多少_国家邮政总局投诉电话是多少

苹果airpods2使用技巧_airpods2使用方法大全 新动态

业绩快报:芭田股份2022年净利润1.2亿 同比增长48.13% 世界新视野

复合肥折纯量_复合肥折纯量怎么计算_天天快资讯

预言ol捡东西文本_预言ol_每日聚焦

网课《营销在移动互联网时代》章节测试答案_全球微速讯

《阴间大法师2》曝动态 珍娜·奥尔特加确定出演|天天新消息

im free是什么意思啊_im free

京长合作取得积极成效,已有总投资超5亿元的2个项目落地

天天精选!国家一级重点保护野生动物林麝首现四川叙永

龙虎榜丨慈文传媒今日跌9.9% 机构合计净卖出6616.42万元_全球速看料

全球快资讯:金融地产携手上攻,“牛市旗手”一季报业绩炸裂,强势录六连阳!“中特估”板块轮番上阵

世界视点!博城影楼软件系统_博城影楼管理系统登录

签收美好,传递正能量 玉泉区举办“红蜂团”骑先锋志愿服务项目签约仪式 当前关注

今日热文:冰箱门封条没磁性关不严怎么办_冰箱门封条没有吸力

全球快看点丨WitsView:5月上旬电视各尺寸面板价格进一步上涨 其他产品均价维持不变

「大雾预警」5月1日白山市气象局发布大雾黄色预警「III级/较重」_动态焦点

世界视点!沁阳市实验小学开展“庆五一·劳动知信行”主题系列教育活动

【环球快播报】小米&瑞声科技相机联合实验室成立!

【天天时快讯】东瑞股份:2023年3月 公司商品猪销售占比约为68%

“五一”假期居民消费意愿增强

科研人员以二氧化碳为原料 实现醋酸“零碳”制造-实时

环球百事通!重仓一二线,金地营收首破千亿

长直发发型扎法图解_长直发发型扎法及步骤

飞上别人的床歌曲_飞上别人的床_今日热门

5月5日 13:02分 东易日盛(002713)股价快速拉升

精彩看点:俄罗斯奥运银牌得主、著名游泳运动员在印度贩毒被抓

每日速讯:宾利对其价值190万美元的汽车有什么计划?

潍坊滨海一中在开发区田径运动会中再创佳绩-世界热资讯