使用Asp.Net MVC进行自动交易的最佳方法是什么?

时间:2009-04-17 19:57:32

标签: asp.net-mvc transactions aop

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

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

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

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

  1. 一个动作过滤器,用于声明性地将某些操作标记为事务性。
  2. 覆盖Controller基类中的OnActionExecuting并一次性处理所有操作事务。
  3. 这些都是好主意吗?我应该注意的任何问题?第二个选项似乎可能是一个很好的方法来解决许多僵局。

    哦是的,我也在使用StructureMap和一个自定义控制器工厂将deps注入我的控制器,以防有人知道一些注入事务的技巧。

2 个答案:

答案 0 :(得分:2)

您可以使用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时,可以在工作单元配置中将混合缓存用作InstanceScope。您可以使用StructureMap将工作单元注入存储库。

答案 1 :(得分:1)

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

OnActionExecuted中,我手动将ISessionProvider从我的容器中拉出来,并在其上调用CommitRollBack,具体取决于是否抛出异常 - 不执行任何操作当然,如果Web请求中当前没有存储会话。

这已被证明是有用的,我认为它表现得非常好 - 大部分时间,应用程序只是读取数据,这不会阻止其他阅读事务。我还没有遇到数据库死锁。

相关问题