EF+Redis(StackExchange.Redis)实现分布式锁,自测可行

释放双眼,带上耳机,听听看~!

电商平台 都会有抢购的情况,比如 1元抢购。 而抢购 最重要的 就是库存,很多情况下  库存处理不好,就会出现超卖现象。

本文将用redis为缓存,StackExchange 框架,消息队列方式 实现分布式锁的情况

一,效果

先看效果,

EF+Redis(StackExchange.Redis)实现分布式锁,自测可行

 

窗体下单 构建高并发情况

EF+Redis(StackExchange.Redis)实现分布式锁,自测可行

开多个控制台应用程序 处理订单

二,配置Redis


1
2
3
4
5
6
7
8
1  <Redis.Service>
2    <DbConfig Name="Order_DBName"  Hosts="127.0.0.1:6379" dbNum="2">
3
4    </DbConfig>
5    <DbConfig Name="Product_DbName" Hosts="127.0.0.1:6379" dbNum="1">
6
7    </DbConfig>
8

模拟用户下单


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1      private void button1_Click(object sender, EventArgs e)
2        {
3            var orderCount = Convert.ToInt32(txt_OrderCount.Text);
4            var productId = Convert.ToInt32(txt_ProductId.Text);
5
6            var productCount = Convert.ToInt32(txt_ProductCount.Text);
7
8            for (int i = 0; i < orderCount; i++)
9            {
10                RedisOrderModel cacheOrder = new RedisOrderModel()
11                {
12                    Count = productCount,
13                    OrderNo = (orderNo += 1).ToString(),
14                    ProductId = productId
15                };
16                orderRedis.Push(cacheOrder);
17            }
18            
19
20        }
21

控制台程序 处理订单


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
33
34
35
36
37
38
39
1public void QueueList()
2        {
3            RedisOrderMessage redis = new RedisOrderMessage();
4            while (true)
5            {
6                try
7                {
8                    var cacheOrder = redis.Pop();
9                    if (cacheOrder == null)
10                    {
11                        Console.WriteLine("无订单,休息100毫秒");
12                        Thread.Sleep(1000);
13                        continue;
14                    }
15
16                    while (ThreadCount<=0)
17                    {
18                        Console.WriteLine("线程已满,休息100毫秒");
19                        Thread.Sleep(100);
20                    }
21                    //ThreadCount--;
22                    Thread thread = new Thread(new ThreadStart(cacheOrder.CreateOrder));
23                    thread.Start();
24                    Console.WriteLine("正在处理订单,休息100毫秒");
25                    Thread.Sleep(100);
26                }
27                catch (Exception ex)
28                {
29                    Console.WriteLine(ex.Message + "," + ex.StackTrace);
30                    Thread.Sleep(1000);
31                }
32                finally
33                {
34                    ThreadCount++;
35                }
36
37            }
38        }
39

 

使用分布式锁,判断库存是否足够


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
33
34
35
36
37
38
39
40
41
42
1 public void LockStore(string productId, int count)
2        {
3            var keyInfo = AddSysCustomKey(productId);
4
5            if (!Exists(keyInfo))
6            {
7                throw new Exception("商品缓存缓存不存在");
8            }
9            var redisConfig = ReadRedisConfig.GetRedisConfig(DB_Name);
10            var lockdb = redisConfig.GetDatabase(-1);
11            var db = redisConfig.GetDatabase();
12            var token = Environment.MachineName;
13            while (true)
14            {
15                //db.LockRelease(keyInfo, token);
16                var con = lockdb.LockTake(keyInfo, token, TimeSpan.FromSeconds(10.0), CommandFlags.None);
17                //var con = db.LockTake(keyInfo, token, TimeSpan.FromSeconds(20), CommandFlags.None);
18                if (con)
19                {
20                    try
21                    {
22                        var product = ConvertObj<CacheProduct>(db.StringGet(keyInfo));
23                        if (product.Count < count)
24                        {
25                            throw new Exception("数量不够,下单失败");
26                        }
27                        product.Count -= count;
28                        var json = ConvertJson(product);
29                        db.StringSet(keyInfo, json);
30                        
31                    }
32                    finally
33                    {
34                        lockdb.LockRelease(keyInfo, token);
35                        
36                    }
37                    break;
38                }
39            }
40          
41        }
42

源码地址:

 

https://github.com/buruainiaaaa/CacheDemo.git

 

给TA打赏
共{{data.count}}人
人已打赏
安全网络

CDN安全市场到2022年价值76.3亿美元

2018-2-1 18:02:50

安全漏洞

22 岁的 Google 工程师:发现了震惊科技界的 CPU 漏洞

2018-1-21 11:12:22

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索