using Microsoft.Extensions.Logging; using SqlSugar; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using WIDESEA_Core.Helper; namespace WIDESEA_Core.BaseRepository { 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 SqlSugarClient GetDbClient() { // 必须要as,后边会用到切换数据库操作 return _sqlSugarClient as SqlSugarClient; } 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 WebResponseContent BeginTran(Func func) { lock (this) { BeginTran(); try { WebResponseContent content = func(); if (content.Status) { CommitTran(); } else { RollbackTran(); } return content; } catch(Exception ex) { RollbackTran(); return WebResponseContent.Instance.Error(ex.Message); } } } 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; } } } } }