分布式锁是一种管理多个应用程序访问同一资源的技术. 主要目的是同一时间只允许多个应用程序中的一个访问资源. 否则, 从不同的应用程序访问同一对象可能会破坏资源。
如果想要在ABP框架调用Redis的分布式锁。需要如下步骤
Step1:安装Volo.Abp.DistributedLocking
我们需要在启动站点项目上添加Volo.Abp.DistributedLocking与DistributedLock.Redis的NuGet引用,注意,我下面的版本号是要和ABP框架对应的,因为我的框架是ABP的8.1.1,所以我用的版本也是8.1.1
dotnet add package Volo.Abp.DistributedLocking --version 8.1.1
dotnet add package DistributedLock.Redis
Step2:修改启动站点的Model,注入Redis服务
之前上面添加的这个库提供了使用分布式锁系统所需的API, 但是, 在使用它之前, 你应该配置一个提供程序,我们以对接Redis为例子
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());
});
}
}
}
Step3:编辑appsettings.json新增Redis的服务地址
因为上面的代码是从配置读取的Redis,所以我们要对应修改配置文件,新增下面一条记录(应该是Redis服务器地址:端口号)
"Redis": {
"Configuration": "127.0.0.1:6379"
}
Step4:配置完成了,下面开始使用锁
我们需要使用IAbpDistributedLock服务,它是ABP框架提供的一个用于简单使用分布式锁的服务,使用方法如下
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)
{
// your code that access the shared resource
}
else
{
throw new UserFriendlyException($"锁被占用!请稍后执行");
}
}
}
}
}
我们可以看到这个TryAcquireAsync方法有三个参数
- name (string, 必须): 锁的唯一名称. 不同的锁命名用于访问不同的资源.
- timeout (TimeSpan): 等待获取锁的超时值. 默认值为TimeSpan.Zero, 这意味着如果锁已经被另一个应用程序拥有, 它不会等待.
- cancellationToken: 取消令牌可在触发后取消操作.
这样,我们就在ABP框架用自带的IAbpDistributedLock服务,实现了对分布式锁的访问