ASP.NET MVC 4中实现action的事务功能

有时候我们的业务逻辑可能涉及多个数据库操作,如下代码片段所示,执行方法Option时,具体执行了3个对应的数据库操作方法,如果Option1执行成功,Option2失败,不采用事务的情况,Option1的结果会影响到数据库,Option2的结果不会影响数据库,这样会出现数据不一致的问题,在针对Option方法增加了事务的情况下,所有的数据库操作,要么全部成功,要么全部失败:

public bool Option1()

{
    数据库操作1...
}

public bool Option2()
{
    数据库操作2...
}

public bool Option3()

{
    数据库操作3...
}
public bool Option()
{
    this.Option1();
    this.Option2();
    this.Option3();
    ...
}

事务的具体实现主要使用了TransactionScope类,具体介绍可参考官方文档:使用事务范围实现隐式事务 - .NET Framework | Microsoft Docs

下面介绍如何在Asp.NET MVC项目中支持Action方法的事务功能。

1、项目中引入程序集System.Transactions

2、实现过滤器,定义自己的事务功能,用于拦截Action,注入事务功能。

    /// <summary>
    /// 事务拦截器,在action方法上增加该特性,可以自动增加事务功能,主要是利用了TransactionScope这个神器类
    /// </summary>
    public class TransactionScopeAttribute: ActionFilterAttribute
    {
        public TransactionScopeAttribute()
        {

        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            using (var txScope = new TransactionScope(TransactionScopeOption.Required))
            {
                try
                {
                    //这里需要手动调用action方法,并且将执行结果赋值给filterContext,并且        return,否则该方法执行完后,目标action方法会重复执行
                    var result = filterContext.ActionDescriptor.Execute(filterContext.Controller.ControllerContext, filterContext.ActionParameters);
                    txScope.Complete();
                    filterContext.Result = (ContentResult)result;
                    return;
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);
        }
    }

3、在需要支持事务功能的action方法上增加特性TransactionScopeAttribute

        /// <summary>
        /// 批准操作
        /// </summary>
        /// <param name="keyValue">主键</param>
        /// <returns></returns>
        [TransactionScopeAttribute()]
        public ActionResult PassAuthorizor(string keyValue, MES_ReleaseEntity entity)
        {
            if (string.IsNullOrEmpty(keyValue))
            {
                return Error($"传递参数keyValue不能为空!");
            }
            var rst = mes_releasebll.PassAuthorizor(keyValue, entity);
            if (rst)
                return Success("处理成功");
            else
                return Error("处理失败!");
        }

猜你喜欢

转载自blog.csdn.net/dandingwangzi/article/details/125430654