예제 #1
0
        /// <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] 则跳过事务
            if (method.IsDefined(typeof(NonTransactAttribute), true))
            {
                // 打印验证跳过消息
                App.PrintToMiniProfiler(MiniProfilerCategory, "Skipped");

                // 继续执行
                await next();

                return;
            }

            // 打印事务开始消息
            App.PrintToMiniProfiler(MiniProfilerCategory, "Beginning");

            // 获取工作单元特性
            UnitOfWorkAttribute unitOfWorkAttribute = null;

            if (!method.IsDefined(typeof(UnitOfWorkAttribute), true))
            {
                unitOfWorkAttribute ??= new UnitOfWorkAttribute();
            }
            else
            {
                unitOfWorkAttribute = method.GetCustomAttribute <UnitOfWorkAttribute>();
            }

            // 开启分布式事务
            using var transaction = new TransactionScope(unitOfWorkAttribute.ScopeOption
                                                         , new TransactionOptions { IsolationLevel = unitOfWorkAttribute.IsolationLevel }
                                                         , unitOfWorkAttribute.AsyncFlowOption);

            // 继续执行
            var resultContext = await next();

            // 判断是否出现异常
            if (resultContext.Exception == null)
            {
                // 将所有上下文提交事务
                var hasChangesCount = await _dbContextPool.SavePoolNowAsync();

                transaction.Complete();

                // 打印事务提交消息
                App.PrintToMiniProfiler(MiniProfilerCategory, "Completed", $"Transaction Completed! Has {hasChangesCount} DbContext Changes.");
            }
            else
            {
                // 打印事务回滚消息
                App.PrintToMiniProfiler(MiniProfilerCategory, "Rollback", isError: true);
            }
        }
예제 #2
0
        /// <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);
                }
            }
        }
예제 #3
0
        /// <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)
                {
                    await _dbContextPool.SavePoolNowAsync();
                }
            }
            else
            {
                // 打印事务开始消息
                App.PrintToMiniProfiler(MiniProfilerCategory, "Beginning");

                var dbContexts = _dbContextPool.GetDbContexts();
                IDbContextTransaction dbContextTransaction;

                // 判断 dbContextPool 中是否包含DbContext,如果是,则使用第一个数据库上下文开启事务,并应用于其他数据库上下文
                if (dbContexts.Any())
                {
                    var firstDbContext = dbContexts.First();
                    dbContextTransaction = await firstDbContext.Database.BeginTransactionAsync();

                    await _dbContextPool.SetTransactionSharedToDbContextAsync(1, dbContextTransaction.GetDbTransaction());
                }
                // 创建临时数据库上下文
                else
                {
                    var newDbContext = Db.GetDbContext(Penetrates.DbContextWithLocatorCached.Keys.First());
                    dbContextTransaction = await newDbContext.Database.BeginTransactionAsync();

                    await _dbContextPool.SetTransactionSharedToDbContextAsync(0, dbContextTransaction.GetDbTransaction());
                }

                // 调用方法
                var resultContext = await next();

                // 判断是否异常
                if (resultContext.Exception == null)
                {
                    try
                    {
                        // 将所有数据库上下文修改 SaveChanges();
                        var hasChangesCount = await _dbContextPool.SavePoolNowAsync();

                        // 提交共享事务
                        await dbContextTransaction.CommitAsync();

                        // 打印事务提交消息
                        App.PrintToMiniProfiler(MiniProfilerCategory, "Completed", $"Transaction Completed! Has {hasChangesCount} DbContext Changes.");
                    }
                    catch
                    {
                        // 回滚事务
                        await dbContextTransaction.RollbackAsync();

                        // 打印事务回滚消息
                        App.PrintToMiniProfiler(MiniProfilerCategory, "Rollback", isError: true);

                        throw;
                    }
                    finally
                    {
                        await dbContextTransaction.DisposeAsync();
                    }
                }
                else
                {
                    // 回滚事务
                    await dbContextTransaction.RollbackAsync();

                    // 打印事务回滚消息
                    App.PrintToMiniProfiler(MiniProfilerCategory, "Rollback", isError: true);
                }

                await dbContextTransaction.DisposeAsync();
            }
        }