This commit is contained in:
tongfei
2024-04-20 11:16:47 +08:00
parent 356253d154
commit 57acf1b699
4 changed files with 61 additions and 38 deletions

View File

@@ -2,7 +2,9 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -25,6 +27,7 @@ using WMS.Web.Domain.Infrastructure;
using WMS.Web.Domain.IService;
using WMS.Web.Domain.IService.Public;
using WMS.Web.Domain.Mappers;
using WMS.Web.Domain.Options;
using WMS.Web.Domain.Values;
using WMS.Web.Domain.Values.Erp;
@@ -51,9 +54,11 @@ namespace WMS.Web.Domain.Services
private readonly IBoxInventoryRepositories _boxInventoryRepositories;
private readonly ILogger<InStockService> _logger;
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly AppOptions _options;
private ConnectionMultiplexer redisMultiplexer;
public StackExchange.Redis.IDatabase _redisDb = null;
private readonly ConcurrentDictionary<int, SemaphoreSlim> _locks = new ConcurrentDictionary<int, SemaphoreSlim>();
public InStockService(IMapper mapper, ISerialNumbersRepositories serialNumbersRepositories, IErpService erpService, IBoxInventoryService boxInventoryService, ISerialNumberService serialNumberService, ILoginService loginService, IBoxRepositories boxRepositories,
public InStockService(IMapper mapper, IOptions<AppOptions> options, ISerialNumbersRepositories serialNumbersRepositories, IErpService erpService, IBoxInventoryService boxInventoryService, ISerialNumberService serialNumberService, ILoginService loginService, IBoxRepositories boxRepositories,
IBasicsRepositories basicsRepositories, IErpBasicDataExtendService erpBasicDataExtendService, IChangeMoveBoxService changeMoveBoxService, IInStockTaskBoxRepositories inStockTaskBoxRepositories,
IInStockRepositories inStockRepositories, IInStockTaskRepositories inStockTaskRepositories, IBoxInventoryRepositories boxInventoryRepositories, ILogger<InStockService> logger, IServiceScopeFactory serviceScopeFactory)
{
@@ -73,6 +78,9 @@ namespace WMS.Web.Domain.Services
_erpBasicDataExtendService = erpBasicDataExtendService;
_serialNumbersRepositories = serialNumbersRepositories;
_boxInventoryRepositories = boxInventoryRepositories;
_options = options?.Value;
redisMultiplexer = ConnectionMultiplexer.Connect(_options.RedisConnectionString);
_redisDb = redisMultiplexer.GetDatabase();
}
/// <summary>
@@ -133,42 +141,53 @@ namespace WMS.Web.Domain.Services
/// <returns></returns>
public async Task<Result> Shelf(PurchaseShelfRequest instock, LoginInDto loginInfo)
{
var taskId= instock.Details.Select(x => x.TaskId).FirstOrDefault();
var taskId = instock.Details.Select(x => x.TaskId).FirstOrDefault();
var taskLock = _locks.GetOrAdd(taskId, _ => new SemaphoreSlim(1, 1));
await taskLock.WaitAsync();
try
// 构建 Redis 锁的键名
string lockKey = $"lock:taskid{taskId}";
// 构建 Redis 锁的值,用于标识锁的持有者
string lockValue = Guid.NewGuid().ToString();
// 获取 Redis 锁,设置超时时间为 10 秒
if (await _redisDb.LockTakeAsync(lockKey, lockValue, TimeSpan.FromSeconds(10)))
{
IDbContextTransaction _transaction = _basicsRepositories.GetTransaction();
bool isRollback = false;
bool isTransaction = false;
//1.添加入库单同步金蝶在save方法里面进行
var save_result = await this.ShelfSave(instock, InstockType.Purchase, loginInfo, isTransaction);
if (!save_result.IsSuccess) isRollback = true;
//实体
var entity = save_result.Data;
//提交事务
var isSuccess = _basicsRepositories.CommitTransaction(isRollback, _transaction);
if (!isSuccess)
return save_result;
//同步金蝶
if (entity.Type == InstockType.Purchase)
try
{
OperateRequest oRequest = new OperateRequest();
oRequest.Ids.Add(entity.Id);
await Sync(oRequest, loginInfo, false);
IDbContextTransaction _transaction = _basicsRepositories.GetTransaction();
bool isRollback = false;
bool isTransaction = false;
//1.添加入库单同步金蝶在save方法里面进行
var save_result = await this.ShelfSave(instock, InstockType.Purchase, loginInfo, isTransaction);
if (!save_result.IsSuccess) isRollback = true;
//实体
var entity = save_result.Data;
//提交事务
var isSuccess = _basicsRepositories.CommitTransaction(isRollback, _transaction);
if (!isSuccess)
return save_result;
//同步金蝶
if (entity.Type == InstockType.Purchase)
{
OperateRequest oRequest = new OperateRequest();
oRequest.Ids.Add(entity.Id);
await Sync(oRequest, loginInfo, false);
}
return Result.ReSuccess();
}
finally
{
// 释放 Redis 锁
await _redisDb.LockReleaseAsync(lockKey, lockValue);
}
return Result.ReSuccess();
}
finally
else
{
taskLock.Release();
return Result.ReFailure(ResultCodes.Concurrent_Instock);
}
}
/// <summary>