【问题标题】:Using multiple NHibernate listeners which make database updates?使用多个 NHibernate 侦听器进行数据库更新?
【发布时间】:2012-01-14 01:04:47
【问题描述】:

我正在使用 NHibernate 2.1,并且有一些实现 IPreInsertEventListener、IPreUpdateEventListener、IPreDeleteEventListener 的侦听器。

两个侦听器执行最后一分钟的数据库操作。两者都与审计相关,但执行非常不同的审计操作,因此有不同的侦听器 - 一个侦听器审计所有内容并写入审计表,另一个只对少数实体类型感兴趣并更新不同表中的数据。

我遇到的问题是,在创建或更新我的审计实体并将它们保存到会话之后,侦听器又会尝试刷新会话,这会触发另一个更新,不久我就会收到 StackOverflowException。

以下是两个不同侦听器的示例:

// Generic audit listener (audits everything)
public bool OnPreUpdate(PreUpdateEvent evnt)
{
    // Ignore audit entries, otherwise we go round and round
    if (!(evnt.Entity == AuditEntry))
    {
        ISession session = evnt.Session.GetSession(EntityMode.Poco);
        // create AuditEntry for the updated Entity
        // ...
        session.Save(auditEntity);
        session.Flush();
    }
}

// Restricted audit listener (only interested in a handful of entities)
public bool OnPreUpdate(PreUpdateEvent evnt)
{
    if (evnt.Entity is RelevantToThisListener) // etc
    {
        ISession session = evnt.Session.GetSession(EntityMode.Poco);
        // create or modify some other audit entity
        // ...
        session.Save(auditEntity);
        session.Flush();
    }
}

一种想法是只有 1 个审计侦听器来适当地委派任务并负责一次刷新。

但在走这条路之前,还有其他选择吗?是否可以启动此事件会话的另一个隔离会话,以便我只刷新新更改?

谢谢

【问题讨论】:

    标签: c# .net hibernate nhibernate


    【解决方案1】:

    选项 1:var isolatedSession = evnt.Session.Factory.OpenSession();

    选项 2:从侦听器中删除 session.Flush();

    我会赞成选项 2,因为

    • 将为审计行启用批处理,立即刷新中断
    • 审核的实体回滚时,审核行也会回滚

    【讨论】:

    • 谢谢。选项 2 对我不起作用,因为没有刷新,新实体在提交时不会写入数据库,有什么想法吗?但是选项 1 确实可以完美运行。
    • 实际上,选项 1 对我不起作用,因为 Flush 确实打破了审核行的回滚。因此,找出选项 2 不起作用的原因会很有帮助。
    • 如果您指定了FlushMode.Never,它不会在提交时刷新,否则它将始终在提交时刷新。也许你在错误的会话上提交或者你的实体没有改变
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    • 2020-11-03
    • 1970-01-01
    • 2013-04-15
    • 2016-08-11
    • 2022-07-14
    相关资源
    最近更新 更多