/// <summary> /// 获取所有数据库上下文 /// </summary> /// <returns>ConcurrentBag{DbContext}</returns> public ConcurrentDictionary <Guid, DbContext> GetDbContexts() { return(_dbContextPool.GetDbContexts()); }
/// <summary> /// 拦截请求 /// </summary> /// <param name="context">动作方法上下文</param> /// <param name="next">中间件委托</param> /// <returns></returns> public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { // 获取动作方法描述器 var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; var method = actionDescriptor.MethodInfo; // 如果方法贴了 [NonTransact] 则跳过事务 var disabledTransact = method.IsDefined(typeof(NonTransactAttribute), true); // 打印验禁止事务信息 if (disabledTransact) { App.PrintToMiniProfiler(MiniProfilerCategory, "Disabled !"); } // 判断是否支持环境事务 var isSupportTransactionScope = _dbContextPool.GetDbContexts().Any(u => !DatabaseProvider.NotSupportTransactionScopeDatabase.Contains(u.Database.ProviderName)); TransactionScope transaction = null; if (isSupportTransactionScope && !disabledTransact) { // 打印事务开始消息 App.PrintToMiniProfiler(MiniProfilerCategory, "Beginning"); // 获取工作单元特性 UnitOfWorkAttribute unitOfWorkAttribute = null; if (!method.IsDefined(typeof(UnitOfWorkAttribute), true)) { unitOfWorkAttribute ??= new UnitOfWorkAttribute(); } else { unitOfWorkAttribute = method.GetCustomAttribute <UnitOfWorkAttribute>(); } // 开启分布式事务 transaction = new TransactionScope(unitOfWorkAttribute.ScopeOption , new TransactionOptions { IsolationLevel = unitOfWorkAttribute.IsolationLevel } , unitOfWorkAttribute.AsyncFlowOption); } // 打印不支持事务 else if (!isSupportTransactionScope && !disabledTransact) { App.PrintToMiniProfiler(MiniProfilerCategory, "NotSupported !"); } // 继续执行 var resultContext = await next(); // 判断是否出现异常 if (resultContext.Exception == null) { // 将所有上下文提交事务 var hasChangesCount = await _dbContextPool.SavePoolNowAsync(); if (isSupportTransactionScope && !disabledTransact) { transaction?.Complete(); transaction?.Dispose(); // 打印事务提交消息 App.PrintToMiniProfiler(MiniProfilerCategory, "Completed", $"Transaction Completed! Has {hasChangesCount} DbContext Changes."); } } else { // 打印事务回滚消息 if (isSupportTransactionScope && !disabledTransact) { App.PrintToMiniProfiler(MiniProfilerCategory, "Rollback", isError: true); } } }
/// <summary> /// 拦截请求 /// </summary> /// <param name="context">动作方法上下文</param> /// <param name="next">中间件委托</param> /// <returns></returns> public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { // 获取动作方法描述器 var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; var method = actionDescriptor.MethodInfo; // 判断是否手动提交 var isManualSaveChanges = method.IsDefined(typeof(ManualSaveChangesAttribute), true); // 判断是否贴有工作单元特性 if (!method.IsDefined(typeof(UnitOfWorkAttribute), true)) { // 调用方法 var resultContext = await next(); // 判断是否异常,并且没有贴 [ManualSaveChanges] 特性 if (resultContext.Exception == null && !isManualSaveChanges) { _dbContextPool.SavePoolNow(); } } else { // 打印事务开始消息 App.PrintToMiniProfiler(MiniProfilerCategory, "Beginning"); var dbContexts = _dbContextPool.GetDbContexts(); IDbContextTransaction dbContextTransaction; // 判断 dbContextPool 中是否包含DbContext,如果是,则使用第一个数据库上下文开启事务,并应用于其他数据库上下文 if (dbContexts.Any()) { // 先判断是否已经有上下文开启了事务 var transactionDbContext = dbContexts.FirstOrDefault(u => u.Value.Database.CurrentTransaction != null); if (transactionDbContext.Value != null) { dbContextTransaction = transactionDbContext.Value.Database.CurrentTransaction; } else { // 如果没有任何上下文有事务,则将第一个开启事务 dbContextTransaction = dbContexts.First().Value.Database.BeginTransaction(); } // 共享事务 _dbContextPool.ShareTransaction(1, dbContextTransaction.GetDbTransaction()); } // 创建临时数据库上下文 else { var newDbContext = Db.GetDbContext(Penetrates.DbContextWithLocatorCached.Keys.First()); // 开启事务 dbContextTransaction = newDbContext.Database.BeginTransaction(); _dbContextPool.ShareTransaction(1, dbContextTransaction.GetDbTransaction()); } // 调用方法 var resultContext = await next(); // 判断是否异常 if (resultContext.Exception == null) { try { // 将所有数据库上下文修改 SaveChanges();,这里另外判断是否需要手动提交 var hasChangesCount = !isManualSaveChanges?_dbContextPool.SavePoolNow() : 0; // 提交共享事务 dbContextTransaction?.Commit(); // 打印事务提交消息 App.PrintToMiniProfiler(MiniProfilerCategory, "Completed", $"Transaction Completed! Has {hasChangesCount} DbContext Changes."); } catch { // 回滚事务 if (dbContextTransaction.GetDbTransaction().Connection != null) { dbContextTransaction?.Rollback(); } // 打印事务回滚消息 App.PrintToMiniProfiler(MiniProfilerCategory, "Rollback", isError: true); throw; } finally { if (dbContextTransaction.GetDbTransaction().Connection != null) { dbContextTransaction?.Dispose(); } } } else { // 回滚事务 if (dbContextTransaction.GetDbTransaction().Connection != null) { dbContextTransaction?.Rollback(); } dbContextTransaction?.Dispose(); // 打印事务回滚消息 App.PrintToMiniProfiler(MiniProfilerCategory, "Rollback", isError: true); } } // 手动关闭 _dbContextPool.CloseAll(); }
/// <summary> /// 拦截请求 /// </summary> /// <param name="context">动作方法上下文</param> /// <param name="next">中间件委托</param> /// <returns></returns> public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { // 获取动作方法描述器 var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; var method = actionDescriptor.MethodInfo; // 判断是否贴有工作单元特性 if (!method.IsDefined(typeof(UnitOfWorkAttribute), true)) { // 调用方法 var resultContext = await next(); // 判断是否异常 if (resultContext.Exception == null) { _dbContextPool.SavePoolNow(); } } else { // 打印事务开始消息 App.PrintToMiniProfiler(MiniProfilerCategory, "Beginning"); var dbContexts = _dbContextPool.GetDbContexts(); IDbContextTransaction dbContextTransaction; // 判断 dbContextPool 中是否包含DbContext,如果是,则使用第一个数据库上下文开启事务,并应用于其他数据库上下文 if (dbContexts.Any()) { var firstDbContext = dbContexts.First(); // 开启事务 dbContextTransaction = firstDbContext.Database.BeginTransaction(); _dbContextPool.ShareTransaction(1, dbContextTransaction.GetDbTransaction()); } // 创建临时数据库上下文 else { var newDbContext = Db.GetRequestDbContext(Penetrates.DbContextWithLocatorCached.Keys.First()); // 开启事务 dbContextTransaction = newDbContext.Database.BeginTransaction(); _dbContextPool.ShareTransaction(1, dbContextTransaction.GetDbTransaction()); } // 调用方法 var resultContext = await next(); // 判断是否异常 if (resultContext.Exception == null) { try { // 将所有数据库上下文修改 SaveChanges(); var hasChangesCount = _dbContextPool.SavePoolNow(); // 提交共享事务 dbContextTransaction?.Commit(); // 打印事务提交消息 App.PrintToMiniProfiler(MiniProfilerCategory, "Completed", $"Transaction Completed! Has {hasChangesCount} DbContext Changes."); } catch { // 回滚事务 dbContextTransaction?.Rollback(); // 打印事务回滚消息 App.PrintToMiniProfiler(MiniProfilerCategory, "Rollback", isError: true); throw; } finally { dbContextTransaction?.Dispose(); } } else { // 回滚事务 dbContextTransaction?.Rollback(); dbContextTransaction?.Dispose(); // 打印事务回滚消息 App.PrintToMiniProfiler(MiniProfilerCategory, "Rollback", isError: true); } } }
/// <summary> /// 获取所有数据库上下文 /// </summary> /// <returns>ConcurrentBag{DbContext}</returns> public ConcurrentBag <DbContext> GetDbContexts() { return(_dbContextPool.GetDbContexts()); }