| 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<UnitOfWorkManage> _logger; | 
|         private readonly ISqlSugarClient _sqlSugarClient; | 
|   | 
|         private int _tranCount { get; set; } | 
|         public int TranCount => _tranCount; | 
|         public readonly ConcurrentStack<string> TranStack = new(); | 
|   | 
|         public UnitOfWorkManage(ISqlSugarClient sqlSugarClient, ILogger<UnitOfWorkManage> logger) | 
|         { | 
|             _sqlSugarClient = sqlSugarClient; | 
|             _logger = logger; | 
|             _tranCount = 0; | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 获取DB,保证唯一性 | 
|         /// </summary> | 
|         /// <returns></returns> | 
|         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<WebResponseContent> 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; | 
|                 } | 
|             } | 
|         } | 
|   | 
|         public async Task UseTranAsync(Func<Task> action) | 
|         { | 
|             // 开始事务 | 
|             _sqlSugarClient.Ado.BeginTran(); | 
|   | 
|             try | 
|             { | 
|                 // 执行传入的操作 | 
|                 await action(); | 
|   | 
|                 // 提交事务 | 
|                 await _sqlSugarClient.Ado.CommitTranAsync(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 // 回滚事务 | 
|                 await _sqlSugarClient.Ado.RollbackTranAsync(); | 
|                 throw new Exception (ex.Message); // 重新抛出异常,以便调用方可以处理 | 
|             } | 
|         } | 
|     } | 
| } |