分布式锁
分布式锁是一种用于管理多个应用程序尝试访问同一资源的技术。其主要目的是确保在任意时刻,多个应用程序中只有一个能够访问同一资源。否则,不同应用程序同时访问同一对象可能导致资源数据损坏。
ABP框架当前的分布式锁实现基于DistributedLock库。
安装
打开命令行终端,输入以下命令将Volo.Abp.DistributedLocking包安装到您的项目中:
abp add-package Volo.Abp.DistributedLocking
该包提供了使用分布式锁系统所需的API,但在使用前需要配置提供程序。
配置提供程序
DistributedLock库为锁机制提供了多种实现方案,例如Redis和ZooKeeper。
若需使用Redis提供程序,请先向项目添加DistributedLock.Redis NuGet包,然后在ABP模块类的ConfigureServices方法中加入以下代码:
using Medallion.Threading;
using Medallion.Threading.Redis;
namespace AbpDemo
{
[DependsOn(
typeof(AbpDistributedLockingModule)
//如有其他依赖项,请在此处添加
)]
public class MyModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
context.Services.AddSingleton<IDistributedLockProvider>(sp =>
{
var connection = ConnectionMultiplexer
.Connect(configuration["Redis:Configuration"]);
return new
RedisDistributedSynchronizationProvider(connection.GetDatabase());
});
}
}
}
此代码从配置中获取Redis连接字符串,因此需在appsettings.json文件中添加以下配置:
"Redis": {
"Configuration": "127.0.0.1"
}
使用方式
分布式锁API有两种使用方式:通过ABP的IAbpDistributedLock抽象接口,或直接使用DistributedLock库的API。
使用IAbpDistributedLock服务
IAbpDistributedLock是ABP为简化分布式锁使用而提供的轻量级服务。
示例:使用IAbpDistributedLock.TryAcquireAsync方法
using Volo.Abp.DistributedLocking;
namespace AbpDemo
{
public class MyService : ITransientDependency
{
private readonly IAbpDistributedLock _distributedLock;
public MyService(IAbpDistributedLock distributedLock)
{
_distributedLock = distributedLock;
}
public async Task MyMethodAsync()
{
await using (var handle =
await _distributedLock.TryAcquireAsync("MyLockName"))
{
if (handle != null)
{
// 访问共享资源的代码
}
}
}
}
}
TryAcquireAsync方法可能无法获取锁。若获取失败将返回null,此时不应访问资源。当句柄非空时,表示已获得锁,可安全访问资源。
该方法接收以下参数:
name(string,必需):锁的唯一名称。不同命名的锁用于访问不同资源。timeout(TimeSpan):获取锁的等待超时时间。默认值为TimeSpan.Zero,表示若锁已被其他应用持有则立即返回。cancellationToken:可用于取消操作的取消令牌。
配置
AbpDistributedLockOptions
AbpDistributedLockOptions是配置分布式锁的主选项类。
示例:为应用程序设置分布式锁键前缀
Configure<AbpDistributedLockOptions>(options =>
{
options.KeyPrefix = "MyApp1";
});
请将上述代码写入模块类的
ConfigureServices方法中。
可用选项
- KeyPrefix (string, 默认值: null): 指定锁名称前缀。
使用DistributedLock库API
ABP的IAbpDistributedLock服务功能有限,主要供框架内部使用。实际开发中建议直接使用DistributedLock库的原生API,详见其官方文档。
Volo.Abp.DistributedLocking.Abstractions包
如果您正在开发可复用库或应用模块,可能不希望为单实例运行的简单应用引入额外依赖。此时,您的库可以依赖Volo.Abp.DistributedLocking.Abstractions包。该包定义了IAbpDistributedLock服务并以进程内方式实现(非真正分布式)。通过这种方式,您的库可在单实例应用中正常运行(无需分布式锁提供程序依赖)。当应用部署到集群环境时,开发者应按安装章节说明安装实际的分布式提供程序。
抠丁客


