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.AspNetCore.Mvc;
|
||||
using Volo.Abp;
|
||||
@@ -19,7 +20,7 @@ public class ActivationCodeService : ApplicationService, IActivationCodeService
|
||||
private readonly ActivationCodeManager _activationCodeManager;
|
||||
private readonly IRechargeService _rechargeService;
|
||||
private readonly PremiumPackageManager _premiumPackageManager;
|
||||
|
||||
private IDistributedLockProvider DistributedLock => LazyServiceProvider.LazyGetRequiredService<IDistributedLockProvider>();
|
||||
public ActivationCodeService(
|
||||
ActivationCodeManager activationCodeManager,
|
||||
IRechargeService rechargeService,
|
||||
@@ -68,6 +69,10 @@ public class ActivationCodeService : ApplicationService, IActivationCodeService
|
||||
[HttpPost("activationCode/Redeem")]
|
||||
public async Task<ActivationCodeRedeemOutput> RedeemAsync(ActivationCodeRedeemInput input)
|
||||
{
|
||||
//自旋等待,防抖
|
||||
await using var handle =
|
||||
await DistributedLock.AcquireLockAsync($"Yi:AiHub:ActivationCodeLock:{input.Code}");
|
||||
|
||||
var userId = CurrentUser.GetId();
|
||||
var redeemContext = await _activationCodeManager.RedeemAsync(userId, input.Code);
|
||||
var goodsType = redeemContext.ActivationCode.GoodsType;
|
||||
|
||||
Reference in New Issue
Block a user