【问题标题】:NHibernate & session-per-conversation in AJAX scenario: manual flush needed?AJAX 场景中的 NHibernate 和会话会话:需要手动刷新吗?
【发布时间】:2011-09-04 14:55:56
【问题描述】:

我们的应用程序面临一个非常奇怪的问题,直到现在我看不到解决问题的选项:

应用程序在每会话会话架构中使用 NHibernate (3.1.x),这意味着在每个 ASP/IIS 请求的开始/结束时,带有新事务的 NHibernate 会话被打开/关闭 + 刷新/提交。

现在,我们在应用程序中有一个邮箱,包括一个简单的邮件网格: 当用户进入邮箱时,第一次填充邮件网格(开始请求创建一个新的 NHibernate 会话/事务,从数据库加载内容,结束请求会话关闭)

删除邮件时出现问题:

(1) 邮件的删除不是通过完整的页面重新加载/刷新发生的,而是调用一个 web 服务,该服务在删除邮件后返回新呈现的 HTML 网格。 这个网络服务通过做一个简单的删除邮件

T_Mails m = T_Mails.GetMailByID( 12345678 );
m.Status = MailStatusDeleted;
NHibernateSession.Update( m );

(2) 在此调用更新邮件之后,相同的函数还重新呈现更新后的邮件网格 - 它通过查询表 T_Mails 中的最后 5 行来完成此操作(一个邮箱页面仅包含 5 行!);然后,这是给定用户邮箱的当前内容。

现在的问题是: 由于这两个调用都发生在 web 服务的同一个函数中(因此在同一个会话/事务范围内),我们想要删除的邮件(在步骤 1 中)不会因为来自 NHibernateSession.Update( m ) 没有到达数据库。

如果我在调试会话时通过 MSSQL ManagementStudio 打开表,我可以看到邮件的状态没有保存到数据库中。

我对这个问题的简单解决方案是: 在更新邮件和重新加载表中的内容之间进行手动 NHibernateSession.Flush() 调用? 但是:这会打破每次会话会话的模式,因为 NhibernateSession.Flush() 是/应该在每个请求结束时发生 - 它不应该在运行请求的某个地方手动调用。

否则我真的被卡住了。

【问题讨论】:

  • 邮件状态更新为已删除后如何查询最后5行?
  • code ICriteria ic = CurrentSession.CreateCriteria(typeof(V_Mailbox)); ic.Add(Expression.Not(Expression.Eq("ReceiverStatusID", T_Mails.StatusDeleted))); ic.List(); code 而 CurrentSession 是用于更新消息的同一会话。另一个注意事项:我没有删除表中的邮件,这不完全是:我通过在邮件行中设置标志“delete=1”使邮件对前端不可见。

标签: ajax nhibernate session flush


【解决方案1】:

您应该进行 2 个 ajax 调用 - 第一个用于删除项目,第二个用于在第一个查询完成时刷新列表。请确保您以相同的顺序拨打电话。下面是使用 jQuery 的示例代码

$.ajax({
    url: 'Mail/Delete',
    data: { mailId: someId },
    success: function (data) {
        $.ajax({
            url: 'Mail/Refresh',
            success: function (data) {
                //here you should put new list into list container
            }
        });
    }
});

【讨论】:

  • Xelibrion,感谢您的意见。是的,打两个电话将是“最终的解决方案”,我已经想到了 - 但是,地狱,我是唯一一个面临这个问题的人吗? 真的没有其他解决方案吗?
  • 这是最简单明了的解决方案。你真的需要另一个吗?
  • 从技术上讲,你是对的:删除和重绘邮件网格是两个不同的操作,所以这个解决方案肯定会起作用 - 但我希望有另一个解决方案不是建立在产生第二个请求(因此是第二个会话+事务),即使这完全符合我们的技术范式。我不明白的是,为什么 NHibernate 不能识别更新的标志,即使它是我用来重绘网格的 same 会话 - 我认为这将适用于这种模式(为什么还要对使用相同的会话感兴趣?:-))
  • NHibernate 不使用一级缓存进行查询 - 它仅适用于 Get/Load 方法。
  • 不不,抱歉:我的评论不是担心,可能不会使用缓存 - 这只是一个“纯技术”评论,我期待“用作 LESS session/transactions as possible”,这就是我寻求另一个解决方案的原因。因此,如果您也表示,最好的解决方案是只进行两次调用(一个用于删除,然后[直接]另一个用于重绘邮件网格),我想我会选择那个解决方案。但我仍然希望任何人有另一个想法,而不是打两个电话......这就是为什么我说:“真的没有其他人面临这个问题吗?”,因为它很常见,我认为?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-28
  • 1970-01-01
  • 1970-01-01
  • 2014-03-11
  • 1970-01-01
  • 2011-01-05
相关资源
最近更新 更多