NHibernate +并发编辑:如何获得变更通知?

时间:2010-11-12 15:40:51

标签: nhibernate concurrency notifications

我正在研究使用NHibernate来处理业务应用程序中的持久层。现在,我想知道如何处理NHibernate中的并发编辑/更新,或者更具体地说,如何让我的应用程序的多个分布式实例知道一个用户更改了给定的数据集。

正在寻找版本控制,即面对并发编辑的一致性 - 我知道NHibernate支持乐观/悲观并发,我目前使用乐观并发来处理{{1} }。

我只想知道:假设用户A更改了数据集中的一行,如何让用户B知道发生了更改,以便可以重新加载数据集?现在,我懒得使用NHibernate将大量客户加载到网格中。现在,如果添加了新客户,我想将其添加到网格中,而无需再次重新加载整个数据 - 应用程序首先关注的是性能。

另外,NHibernate会优雅地处理对现有行的更改吗?它会以某种方式检测底层数据库中的更改并更新内存中的.NET对象,以便访问其属性将产生更新的值吗?

我想过使用一个额外的表,保存更新对象的ID以及时间戳来自己刷新项目,但如果NHinbernate提供了自己的东西,那将是一个很好的选择,显然......

2 个答案:

答案 0 :(得分:3)

您需要数据库级别的通知/事件。也就是说,数据库引擎必须提供通知。例如,SQL Server has this feature。 NHibernate在应用程序上运行,因此可能单独执行所有轮询数据库以进行更改(您使用附加表的想法看起来像轮询),我们所有人知道这不好。当数据库引发通知时,NHibernate的SysCache2利用SqlCacheDependencies使缓存条目无效,但我不知道它可以引发应用程序本身消耗的任何事件(无论如何这都不会有用,因为第二级缓存不适用于整个实体。)

实现这一点的另一种可能方法是让NHibernate事件监听器在任何更新后在总线上放置广播消息,然后每个应用程序实例都会收到此消息并相应地从数据库中重新获取。

答案 1 :(得分:0)

我必须在我当前的SQLite Fluent NHibernate项目中解决一些类似的问题。

为了检测数据库更新,我使用了 System.IO.FileSystemWatcher 。请参阅示例代码in my answer to my own, similar, question。另外,请看一下同一个问题的另一个答案,建议使用 NHibernate拦截器

我也懒得将我的数据库加载到网格中。每当FileSystemWatcher检测到数据库已更新时,我调用以下 Criteria Query ,并将它返回的新记录添加到BindingList,它是我的网格的DataSource。 (我只是将新记录的最高ID保存在私有变量中)

    /// <summary>
    /// Return list of measurements with Id fields higher than id parameter
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public static IList<T> GetMeasurementsNewerThan(int id)
    {
        var session = GetMainSession();

        using (var transaction = session.BeginTransaction())
        {
            var newestMeasurements =
                session.CreateCriteria(typeof(T))
                       .Add(Expression.Gt("Id", id))
                       .List<T>();

            transaction.Commit();

            return newestMeasurements;
        }
    }