using System; using System.Collections.Concurrent; using System.Reflection; using System.Threading; using EntrustSettle.Common.Extensions; using Microsoft.Extensions.Logging; using SqlSugar; namespace EntrustSettle.Repository.UnitOfWorks { public class UnitOfWorkManage : IUnitOfWorkManage { private readonly ILogger _logger; private readonly ISqlSugarClient _sqlSugarClient; private int _tranCount { get; set; } public int TranCount => _tranCount; public readonly ConcurrentStack TranStack = new(); public UnitOfWorkManage(ISqlSugarClient sqlSugarClient, ILogger logger) { _sqlSugarClient = sqlSugarClient; _logger = logger; _tranCount = 0; } /// /// 获取DB,保证唯一性 /// /// public SqlSugarScope GetDbClient() { // 必须要as,后边会用到切换数据库操作 return _sqlSugarClient as SqlSugarScope; } public UnitOfWork CreateUnitOfWork() { UnitOfWork uow = new UnitOfWork(); uow.Logger = _logger; uow.Db = _sqlSugarClient; uow.Tenant = (ITenant) _sqlSugarClient; uow.IsTran = true; uow.Db.Open(); uow.Tenant.BeginTran(); _logger.LogDebug("UnitOfWork Begin"); return uow; } public void BeginTran() { lock (this) { _tranCount++; GetDbClient().BeginTran(); } } public void BeginTran(MethodInfo method) { lock (this) { GetDbClient().BeginTran(); TranStack.Push(method.GetFullName()); _tranCount = TranStack.Count; } } public void CommitTran() { lock (this) { _tranCount--; if (_tranCount == 0) { try { GetDbClient().CommitTran(); } catch (Exception ex) { Console.WriteLine(ex.Message); GetDbClient().RollbackTran(); } } } } public void CommitTran(MethodInfo method) { lock (this) { string result = ""; while (!TranStack.IsEmpty && !TranStack.TryPeek(out result)) { Thread.Sleep(1); } if (result == method.GetFullName()) { try { GetDbClient().CommitTran(); _logger.LogDebug($"Commit Transaction"); Console.WriteLine($"Commit Transaction"); } catch (Exception ex) { Console.WriteLine(ex.Message); GetDbClient().RollbackTran(); _logger.LogDebug($"Commit Error , Rollback Transaction"); } finally { while (!TranStack.TryPop(out _)) { Thread.Sleep(1); } _tranCount = TranStack.Count; } } } } public void RollbackTran() { lock (this) { _tranCount--; GetDbClient().RollbackTran(); } } public void RollbackTran(MethodInfo method) { lock (this) { string result = ""; while (!TranStack.IsEmpty && !TranStack.TryPeek(out result)) { Thread.Sleep(1); } if (result == method.GetFullName()) { GetDbClient().RollbackTran(); _logger.LogDebug($"Rollback Transaction"); Console.WriteLine($"Rollback Transaction"); while (!TranStack.TryPop(out _)) { Thread.Sleep(1); } _tranCount = TranStack.Count; } } } } }