加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

何时在ASP.NET MVC 2应用程序中提交NHibernate事务?

发布时间:2020-12-16 07:43:52 所属栏目:asp.Net 来源:网络整理
导读:首先,一些背景:我是ASP.NET MVC 2和NHibernate的新手.我正在开始我的第一个应用程序,我想使用NHibernate,因为我来自JSP Struts 1 Hibernate Web应用程序. 似乎没有人在谈论这个,所以我想这一定是非常明显的.我仍然挠头,因为我找不到能够完成以下事情的解决
首先,一些背景:我是ASP.NET MVC 2和NHibernate的新手.我正在开始我的第一个应用程序,我想使用NHibernate,因为我来自JSP Struts 1 Hibernate Web应用程序.

似乎没有人在谈论这个,所以我想这一定是非常明显的.我仍然挠头,因为我找不到能够完成以下事情的解决方案:

1)我想使用“每个请求的会话”策略.因此,每次用户发出请求时,他都会获得Nhibernate会话,启动事务,当请求结束时,事务提交,NHibernate会话关闭(如果存在则返回池).这保证了我的交易是原子的.

2)当发生数据库异常(PK违规,唯一违规,无论如何)时,我想捕获该异常,回滚我的事务并给用户一个明确的消息:如果是PK违规,那么该消息,以及所有完整性相同错误.

那么,我的问题是什么?我来自Java World,我使用Filter打开会话,处理请求,然后提交事务并关闭会话.这有效,除非发生数据库异常,并且当您进入过滤器时,无法更改目标页面,因为响应已提交.

因此,当实际交易被回滚时,用户会看到成功页面.为了避免这种情况,我必须在Java中编写大量数据完整性检查,以防止所有完整性异常,因为我无法正确处理它们.这很糟糕,因为我正在做的工作而不是把它留给数据库(或者我错了,我总是要在我的应用程序中编写所有这些数据完整性代码?).

所以我发现我猜的IHttpModule接口与javax.servlet.Filter的概念基本相同(如果我错了,请纠正我),所以我猜我可能会再遇到同样的问题.

我应该在哪里提交我的提交以确保我的事务是原子的,当它们抛出异常时我可以捕获它们并更改我的目标页面并给用户一个全面的消息?

到目前为止,我提出的唯一可能的解决方案是保持我的IHttpModule启动和关闭事务,并将提交调用放在我的控制器方法的最后一行,从而能够捕获那里的异常,然后返回适当的查看消息.现在我必须将这些提交和异常处理行复制到我需要提交的所有控制器方法中.并且存在关注点分离问题,我的控制器必须知道DB,我完全不喜欢它.

有没有更好的办法?

解决方法

如果您使用的是ASP.NET MVC,则可以使用 ActionFilter来实现相同的效果.

类似的东西(这是从我的架构的不同部分一起被黑客攻击):

public class TransactionalAttribute : ActionFilterAttribute,IAuthorizationFilter,IExceptionFilter
{

    ITransaction transaction = NullTransaction.Instance;
    public IsolationLevel IsolationLevel { get; set; } 

    public TransactionalAttribute() 
    {
        IsolationLevel = IsolationLevel.ReadCommitted;
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        try
        {
            transaction.Commit();
            transaction = NullTransaction.Instance;
        }
        catch (Exception exception)
        {
            Log.For(this).FatalFormat("Problem trying to commit transaction {0}",exception);
        }

    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (transaction == NullTransaction.Instance) transaction = UnitOfWork.Current.BeginTransaction(IsolationLevel);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.Result != null) return;

        transaction.Commit();
        transaction = NullTransaction.Instance;
    }

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        transaction = UnitOfWork.Current.BeginTransaction(IsolationLevel);
    }

    public void OnException(ExceptionContext filterContext)
    {
        try
        {
            transaction.Rollback();
            transaction = NullTransaction.Instance;
        }
        catch (Exception exception)
        {
            Log.For(this).FatalFormat("Problem trying to rollback transaction {0}",exception);
        }
    }

    private class NullTransaction : ITransaction
    {
        public static ITransaction Instance { get { return Singleton<NullTransaction>.Instance; } }

        public void Dispose()
        {

        }

        public void Commit()
        {
        }

        public void Rollback()
        {
        }
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读