fix: 为领奖与兑换流程添加分布式锁,防止并发重复操作
- 在 DailyTaskService 与 ActivationCodeService 中引入 Medallion.Threading。 - 通过 LazyServiceProvider 获取 IDistributedLockProvider(DistributedLock 属性)。 - 在 ClaimTaskRewardAsync(DailyTaskService)和 RedeemAsync(ActivationCodeService)中使用 AcquireLockAsync 加锁(基于 userId / activation code),用于自旋等待、防抖,避免并发导致的重复发放或重复兑换问题。
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using Medallion.Threading;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SqlSugar;
|
||||
@@ -23,7 +24,7 @@ public class DailyTaskService : ApplicationService
|
||||
private readonly ISqlSugarRepository<MessageAggregateRoot> _messageRepository;
|
||||
private readonly ISqlSugarRepository<PremiumPackageAggregateRoot> _premiumPackageRepository;
|
||||
private readonly ILogger<DailyTaskService> _logger;
|
||||
|
||||
private IDistributedLockProvider DistributedLock => LazyServiceProvider.LazyGetRequiredService<IDistributedLockProvider>();
|
||||
// 任务配置
|
||||
private readonly Dictionary<int, (long RequiredTokens, long RewardTokens, string Name, string Description)>
|
||||
_taskConfigs = new()
|
||||
@@ -113,6 +114,11 @@ public class DailyTaskService : ApplicationService
|
||||
public async Task ClaimTaskRewardAsync(ClaimTaskRewardInput input)
|
||||
{
|
||||
var userId = CurrentUser.GetId();
|
||||
//自旋等待,防抖
|
||||
await using var handle =
|
||||
await DistributedLock.AcquireLockAsync($"Yi:AiHub:ClaimTaskRewardLock:{userId}");
|
||||
|
||||
|
||||
var today = DateTime.Today;
|
||||
|
||||
// 1. 验证任务等级
|
||||
|
||||
Reference in New Issue
Block a user