微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

分布式锁不适用于RedLock.net

如何解决分布式锁不适用于RedLock.net

我想使用Redis进行分布式锁定。我为此使用了RedLock.net nuget包。 但是线程能够获取锁,即使另一个线程已经获取了锁。

以下是示例代码

public void Demo(RedLockFactory redLockFactory)
        {
            Parallel.For(0,5,x =>
            {
                TimeSpan expiry = TimeSpan.FromSeconds(30);
                var wait = TimeSpan.FromSeconds(10);
                var retry = TimeSpan.FromSeconds(1);

                string user = $"User:{x}";
                using (var redLock = redLockFactory.CreateLock(resource,expiry,wait,retry))
                {

                    // make sure we got the lock
                    if (redLock.IsAcquired)
                    {
                        Console.WriteLine($"{user} acquired lock at {DateTimeOffset.Now.ToString("dd-MM-yyyy HH:mm:ss")}.");
                    }
                    else
                    {
                        Console.WriteLine($"{user} didn't get the lock.");
                    }
                }
            });
        }

这是我的演示的输出

User:4 acquired lock at 06-10-2020 09:24:34.
User:2 acquired lock at 06-10-2020 09:24:34.
User:1 acquired lock at 06-10-2020 09:24:34.
User:0 acquired lock at 06-10-2020 09:24:35.
User:3 acquired lock at 06-10-2020 09:24:35.

如您所见,每个线程都可以获取该锁,这应该不会发生。

一旦获得了锁,其他线程就将无法获得该锁。

解决方法

RedLock.net/README.md,“该锁会在using块的末尾自动释放”。

所以我认为您的演示输出中发生的是:

  1. 五个线程并行启动,每个线程都试图锁定同一资源。
  2. 线程4获胜(成功获得其锁)并执行以下操作;同时,其他线程等待(最多10秒):
    • 将“获得的锁”写入控制台
    • using块中传递出去,释放其锁(现在另一个线程可以获胜)
  3. 线程2获胜并且在其余线程等待时执行相同的操作。
  4. Ditto用于线程1、0和3。
  5. 每个线程都能快速完成工作,因此没有一个线程会在10秒内获取锁。

如果您希望锁获取失败,请在退出using块之前进行非常缓慢的操作(> 10秒)。出于演示目的,您可以在编写“ acquired”行之后Thread.Sleep(15000)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。