项目地址
GitHub - samcook/RedLock.net: An implementation of the Redlock algorithm in C#
基本使用
初始化RedLockFactory
var multiplexers = new List<RedLockMultiplexer>
{
	ConnectionMultiplexer.Connect("redis1:6379"),
	ConnectionMultiplexer.Connect("redis2:6379"),
	ConnectionMultiplexer.Connect("redis3:6379")
};
var redlockFactory = RedLockFactory.Create(multiplexers);
乐观锁
不进行阻塞操作,只通过IsAcquired判定是否已经锁了
var resource = "the-thing-we-are-locking-on";
var expiry = TimeSpan.FromSeconds(30);
await using (var redLock = await redlockFactory.CreateLockAsync(resource, expiry)) // there are also non async Create() methods
{
	// make sure we got the lock
	if (redLock.IsAcquired)
	{
		// do stuff
	}
}
// 当using结束时将自动释放锁
// the lock is automatically released at the end of the using block
悲观锁
进行阻塞操作,直到锁释放,或者等待时间结束(下面的wait)
var resource = "the-thing-we-are-locking-on";
var expiry = TimeSpan.FromSeconds(30);
var wait = TimeSpan.FromSeconds(10);
var retry = TimeSpan.FromSeconds(1);
// blocks until acquired or 'wait' timeout
await using (var redLock = await redlockFactory.CreateLockAsync(resource, expiry, wait, retry)) // there are also non async Create() methods
{
	// make sure we got the lock
	if (redLock.IsAcquired)
	{
		// do stuff
	}
}
// the lock is automatically released at the end of the using block
依赖注入示例代码
public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDistributedLockFactory, RedLockFactory>(
        x => RedLockFactory.Create(/* endpoints */)
    );
}
public class MyClass
{
    private readonly IDistributedLockFactory factory;
    public MyClass(IDistributedLockFactory factory)
    {
        this.factory = factory;
    }
    public void DoSomething()
    {
        using (var redlock = this.factory.CreateLock("foo", TimeSpan.FromSeconds(30)))
        {
            if (redlock.IsAcquired) { /* ... */ }
        }
    }
}
Moq Test
[Test]
public void Test()
{
    var mockRedLock = new Mock<IRedLock>();
    mockRedLock.Setup(x => x.IsAcquired).Returns(true);
    var mockFactory = new Mock<IDistributedLockFactory>();
    mockFactory.Setup(x => x.CreateLock(It.IsAny<string>(), It.IsAny<TimeSpan>())).Returns(mockRedLock.Object);
    var subject = new MyClass(mockFactory.Object);
    subject.DoSomething();
    Assert.That(/* whatever */);
}
 站点公众号
                站点公众号