分布式锁


  以上的锁都只能用于单体应用中,所以称之为本地锁。对于分布式应用,必须使用分布式锁来保证业务数据的正确性,比如订单与库存处理的业务代码,必须保证库存量不能为零且按顺序递减。


1、获得实例

  要使用分布式锁,首先得获取到它的实例。我们不推荐使用 new 构造一个实例,而是使用 DistributedLockerFactory 工厂类来创建一个实例。该工厂类提供一个 CreateLocker 方法,可以接收一个 configName 参数,这个参数对应分布式锁配置(可参考 配置与扩展)中配置项的名称,如果未配置分布式锁配置项,则返回默认的分布式锁单例。如下所示:

[TestMethod]
public void TestCreateLocker()
{
    var locker = DistributedLockerFactory.CreateLocker();
    Assert.IsNotNull(locker);
}

  在使用 IOC 的环境中,也可以通过构造注入或属性注入得到 IDistributedLocker 的实例。如下所示:

public class HomeController : Controller
{
    private readonly IDistributedLocker _distributedLocker;

    public HomeController(IDistributedLocker distributedLocker)
    {
        _distributedLocker = distributedLocker;
    }
}

2、使用方法

  IDistributedLocker 接口定义了分布式锁的方法。使用 Lock 方法时,需要指定一个 token 作为分布式环境中唯一的令牌,并且指定锁定的时间。如下所示:

[TestMethod]
public void TestDistributedLock()
{
    var locker = DistributedLockerFactory.CreateLocker();
    locker.Lock("CREATE_ORDER", TimeSpan.FromSeconds(10), () =>
    {
        //处理业务代码
    });
}

[TestMethod]
public async Task TestDistributedLockAsync()
{
    var locker = DistributedLockerFactory.CreateLocker();
    var code = await locker.LockAsync("CREATE_ORDER", TimeSpan.FromSeconds(10), async () =>
    {
        return await CreateOrderAsync();
    });
}

private async Task<string> CreateOrderAsync()
{
    //订单处理逻辑,返回订单号
}