欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

redis使用Lua腳本解決多線程下的超賣問題及原因解析

 更新時間:2023年05月08日 09:23:05   作者:David.Meng  
這篇文章主要介紹了redis使用Lua腳本解決多線程下的超賣問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

一.多線程下引起的超賣問題呈現(xiàn)

1.1.我先初始化庫存數(shù)量為1、訂單數(shù)量為0

1.2.開啟3個線程去執(zhí)行業(yè)務

業(yè)務為:判斷如果說庫存數(shù)量大于0,則庫存減1,訂單數(shù)量加1

結果為:庫存為-2,訂單數(shù)量為3

原因:如下圖所示,這是因為分別有6個指令(3個庫存減1指令,3個訂單數(shù)量加1指令)在redis服務端執(zhí)行導致的。

namespace MengLin.Shopping.Redis.LuaScript
{
    public class SecKillOriginal
    {
        static SecKillOriginal()
        {
            using (RedisClient client = new RedisClient("127.0.0.1", 6379))
            {
                //刪除當前數(shù)據(jù)庫中的所有Key, 默認刪除的是db0
                client.FlushDb();
                //刪除所有數(shù)據(jù)庫中的key 
                client.FlushAll();
                //初始化庫存數(shù)量為1和訂單數(shù)量為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<int>("inventoryNum");
                        //如果庫存數(shù)量大于0
                        if (inventoryNum > 0)
                        {
                            //給庫存數(shù)量-1
                            var inventoryNum2 = client.Decr("inventoryNum");
                            Console.WriteLine($"給庫存數(shù)量-1后的數(shù)量-inventoryNum: {inventoryNum2}");
                            //給訂單數(shù)量+1
                            var orderNum = client.Incr("orderNum");
                            Console.WriteLine($"給訂單數(shù)量+1后的數(shù)量-orderNum: {orderNum}");
                        }
                        else
                        {
                            Console.WriteLine($"搶購失敗: 原因是因為沒有庫存");
                        }
                    }
                });
            }
        }
    }
}

二.使用Lua腳本解決多線程下超賣的問題以及為什么

2.1.修改后的代碼如下

結果為:如下圖所示,庫存為0、訂單數(shù)量為1,并沒有出現(xiàn)超賣的問題且有2個線程搶不到。

namespace MengLin.Shopping.Redis.LuaScript
{
    public class SecKillLua
    {
        /// <summary>
        /// 使用Lua腳本解決多線程下變賣的問題
        /// </summary>
        static SecKillLua()
        {
            using (RedisClient client = new RedisClient("127.0.0.1", 6379))
            {
                //刪除當前數(shù)據(jù)庫中的所有Key, 默認刪除的是db0
                client.FlushDb();
                //刪除所有數(shù)據(jù)庫中的key 
                client.FlushAll();
                //初始化庫存數(shù)量為1和訂單數(shù)量為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))
                    {
                        //如果庫存數(shù)量大于0,則給庫存數(shù)量-1,給訂單數(shù)量+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個指令,分別是:判斷庫存數(shù)量是否大于0、庫存減1、訂單數(shù)量加1,這3個指令打包放在一起執(zhí)行了且不能分割,相當于組裝成了原子指令,所以避免了超賣問題。

在redis中我們盡量使用原子指令從而避免一些并發(fā)的問題。

到此這篇關于redis使用Lua腳本解決多線程下的超賣問題以及為什么的文章就介紹到這了,更多相關redis多線程超賣內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 基于Redis無序集合如何實現(xiàn)禁止多端登錄功能

    基于Redis無序集合如何實現(xiàn)禁止多端登錄功能

    這篇文章主要給你大家介紹了關于基于Redis無序集合如何實現(xiàn)禁止多端登錄功能的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-12-12
  • redis數(shù)據(jù)一致性之延時雙刪策略詳解

    redis數(shù)據(jù)一致性之延時雙刪策略詳解

    在使用redis時,需要保持redis和數(shù)據(jù)庫數(shù)據(jù)的一致性,最流行的解決方案之一就是延時雙刪策略,今天我們就來詳細刨析一下,需要的朋友可以參考下
    2023-09-09
  • Redis鎖完美解決高并發(fā)秒殺問題

    Redis鎖完美解決高并發(fā)秒殺問題

    本文主要介紹了Redis鎖完美解決高并發(fā)秒殺問題,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Redis列表類型的常用命令小結

    Redis列表類型的常用命令小結

    這篇文章給大家整理了在操作Redis列表類型中的常用命令,文章總結的很全面,對大家學習Redis具有一定的參考借鑒價值,下面來一起看看吧。
    2016-09-09
  • Redis 對過期數(shù)據(jù)的處理方法

    Redis 對過期數(shù)據(jù)的處理方法

    這篇文章主要介紹了Redis 對過期數(shù)據(jù)的處理,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • Govern Service 基于 Redis 的服務治理平臺安裝過程詳解

    Govern Service 基于 Redis 的服務治理平臺安裝過程詳解

    Govern Service 是一個輕量級、低成本的服務注冊、服務發(fā)現(xiàn)、 配置服務 SDK,通過使用現(xiàn)有基礎設施中的 Redis 不用給運維部署帶來額外的成本與負擔,接下來通過本文給大家分享Govern Service 基于 Redis 的服務治理平臺的相關知識,感興趣的朋友一起看看吧
    2021-05-05
  • redis-cli登錄遠程redis服務并批量導入數(shù)據(jù)

    redis-cli登錄遠程redis服務并批量導入數(shù)據(jù)

    本文主要介紹了redis-cli登錄遠程redis服務并批量導入數(shù)據(jù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-10-10
  • Redis高性能的原因及說明

    Redis高性能的原因及說明

    這篇文章主要介紹了Redis高性能的原因及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Redis?Lua腳本實現(xiàn)ip限流示例

    Redis?Lua腳本實現(xiàn)ip限流示例

    這篇文章主要介紹了Redis?Lua腳本實現(xiàn)ip限流示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Redis進行相關優(yōu)化詳解

    Redis進行相關優(yōu)化詳解

    這篇文章主要介紹了Redis進行相關優(yōu)化,Redis在項目中進行廣泛使用,那么在日常的開發(fā)過程中,我們在使用Redis的過程中需要注意那些呢?本文將從三個維度來講解如何進行Redis的優(yōu)化
    2022-08-08

最新評論