【问题标题】:What is the best way to do automatic transactions with Asp.Net MVC?使用 Asp.Net MVC 进行自动事务的最佳方法是什么?
【发布时间】:2009-04-18 16:58:27
【问题描述】:

我对在我的 MVC 应用程序中到处写以下代码感到恼火。

using(var tx = new TransactionScope()){
   blah...
   tx.Complete()
}

我想以某种方式制作这款 DRYer。

我为此想到了几个不同的选择。

  1. 一个动作过滤器,以声明方式将某些动作标记为事务性。
  2. 在 Controller 基类中重写 OnActionExecuting 并使所有操作一次性成为事务性操作。

这些都是好主意吗?有什么我应该注意的问题吗?第二个选项似乎是获得大量死锁的好方法。

哦,是的,我还使用 StructureMap 和自定义控制器工厂将 deps 注入到我的控制器中,以防有人知道以这种方式注入事务的一些技巧。

【问题讨论】:

    标签: asp.net-mvc transactions aop


    【解决方案1】:

    您可以使用Unit of Work pattern 进行交易管理。工作单元模式的主要好处是您可以将事务策略保存在一个地方,或者当您有多个策略时,可以将其保存在几个地方。 最简单的工作单元界面可能是:

    public interface IUnitOfWork
    {
        void Start();
        void Commit();
        void RollBack();
    }
    

    您可以为不同的 ORM 或存储过程或硬编码的 sql 创建各种 UnitOfWork 实现。您可以在请求开始时启动事务。事务可以在请求结束时处理。在处理之前,您可以将提交包装在 try-catch 块中,并在 catch 中回滚。

    try
    {
        unitOfWork.Commit();
    } 
    catch
    {
         unitOfWork.RollBack();
         throw;
    }
    

    事务启动策略有:

    • 每个请求:一个事务用于整个请求,这是大多数情况下的最佳方式。
    • 每个请求多次:每个方法一个事务。
    • 每次对话:您可以围绕购物车结账流程的多个请求创建交易。

    您可以通过以下方式管理您的交易:

    • 属性
    • global.asax 中的 application_begin 和 endrequest 方法
    • http模块

    使用 StructureMap 时,您可以在工作单元配置中使用 Hybrid 缓存作为 InstanceScope。您可以使用 StructureMap 将工作单元注入到存储库中。

    【讨论】:

      【解决方案2】:

      在我目前正在开发的应用程序中,我的存储库从ISessionProvider 中获得一个NHibernate ISession,该ISessionProvider 被注入到构造函数中。会话提供者是一个AspNetMvcSessionProvider,它将创建一个ISession,并在第一次调用ISessionProvider.OpenSession() 时开始一个事务,将ISession 存储在当前的Web 请求中。

      OnActionExecuted 中,我手动将ISessionProvider 从我的容器中拉出并调用CommitRollBack,具体取决于是否引发了异常 - 如果当前没有存储会话,当然什么也不做在网络请求中。

      这已被证明是有用的,而且我认为它表现得相当好 - 大多数时候,应用程序只是读取数据,不会阻塞其他读取事务。我还没有遇到数据库死锁。

      【讨论】:

        猜你喜欢
        • 2012-10-08
        • 2011-03-16
        • 1970-01-01
        • 2010-09-13
        • 1970-01-01
        • 1970-01-01
        • 2012-04-08
        • 1970-01-01
        • 2012-09-07
        相关资源
        最近更新 更多