0

在我的 Web 应用程序中,在请求周期的某个地方,我在存储库上调用以下方法:

     repository.Delete(objectToDelete);   

这是 NHibernate 实现:

    public void Delete(T entity)
    {
        if (!session.Transaction.IsActive)
        {
            using (ITransaction transaction = session.BeginTransaction())
            {
                session.Delete(entity);
                transaction.Commit();
            }
        }
        else
        {
            session.Delete(entity);
        }
    }

并且session.Delete(entity)(在 using 语句内)失败 - 这很好,因为我有一些数据库限制,这是我所期望的。但是,在Global.asax.cs中的请求结束时,我使用以下代码关闭会话:

    protected void Application_EndRequest(object sender, EventArgs e)
    {
        ISession session = ManagedWebSessionContext.Unbind(HttpContext.Current, sessionFactory);

        if (session != null)
        {
            if (session.Transaction != null && session.Transaction.IsActive)
            {
                session.Transaction.Rollback();
            }
            else
            {
                session.Flush();
            }
            session.Close();
        }
    }

这是用于删除对象的同一会话。现在,当:

session.Flush();

被调用时,NHibernate 会尝试执行相同的 DELETE 操作——这会引发异常和应用程序崩溃。不完全是我想要的,因为我之前已经处理过异常(在存储库级别)并且我显示了 preety UI 消息框。

当调用 session.Flush 时,如何防止 NHibernate 再次尝试执行 DELETE(我猜在其他情况下是 UPDATE 操作)操作。基本上我还没有设计Application_EndRequest所以我不确定它是否是刷新所有内容的好方法。

谢谢

4

1 回答 1

1

NHibernate 的刷新模式默认设置为“自动”,这意味着(除其他外)提交事务将导致 NHibernate 刷新并且删除失败。

在请求结束时,您再次手动刷新会话,告诉 NHibernate 再次执行删除(因为没有活动事务)。

这没有按预期工作的原因是因为您的期望是错误的。NHibernate 会话是一个工作单元,即您的应用程序在一个请求中执行的所有操作。交易完全不相关。第一次刷新会话失败的事实也是第二次失败的原因。

如果你想阻止 NHibernate 第二次执行删除,你不应该刷新两次,只刷新一次。通过提交事务或手动进行。

在一个有点不相关的注意事项上:您正在使用 NHibernate 并且事务错误。以后会给你带来很大的问题。网上有一些关于如何在 Web 应用程序中使用 NHibernate 的好资源。

于 2012-07-17T12:40:43.303 回答