fix: 为领奖与兑换流程添加分布式锁,防止并发重复操作

- 在 DailyTaskService 与 ActivationCodeService 中引入 Medallion.Threading。
- 通过 LazyServiceProvider 获取 IDistributedLockProvider(DistributedLock 属性)。
- 在 ClaimTaskRewardAsync(DailyTaskService)和 RedeemAsync(ActivationCodeService)中使用 AcquireLockAsync 加锁(基于 userId / activation code),用于自旋等待、防抖,避免并发导致的重复发放或重复兑换问题。
This commit is contained in:
chenchun
2025-12-19 16:13:23 +08:00
parent 7f0d57b311
commit 4326c41258
2 changed files with 13 additions and 2 deletions

View File

@@ -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. 验证任务等级