NHibernate +并发编辑:如何收到更改通知?

发布于 2024-10-02 12:16:40 字数 552 浏览 0 评论 0原文

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

在寻找版本控制,即并发编辑时的一致性 - 我知道 NHibernate 支持乐观/悲观并发,并且我目前通过处理 StateStateException

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

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

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

I'm looking into using NHibernate to handle the persistence layer in my business application. Right now, I'm wondering how to handle concurrent edits/updates in NHibernate, or more specifically, how to let multiple, distributed instances of my application know that one user changed a given dataset.

I'm not looking for versioning, i.e. consistency in the face of concurrent edits - I know NHibernate supports optimistic/pessimistic concurrency, and I currently use optimistic concurrency via and handling the StateStateException.

I just want to know: Given that user A changes a row in the dataset, how to let user B know that a change occured so that the dataset can be reloaded? Right now, I'm lazy loading a large list of customers into a grid using NHibernate. Now, if a new customer is added, I'd like to add it to the grid without reloading the whole data again - the application's first concern is performance.

Also, will NHibernate gracefully handle changes to existing rows? Will it somehow detect changes in the underlying database and update the in-memory .NET objects so that accessing their properties will yield the updated values?

I thought about using an additional table, saving the IDs of updated objects along with a timestamp to refresh items myself, but if NHinbernate offers something of it's own, that would be a much bett choice, obviously...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

2024-10-09 12:16:40

为此,您需要数据库级通知/事件。也就是说,数据库引擎必须提供通知。例如,SQL Server 具有此功能。 NHibernate 在应用程序上运行,因此它本身可能可以做的就是轮询数据库中的更改(您使用附加表的想法看起来像轮询),并且我们都知道那不好。 NHibernate 的 SysCache2 利用 SqlCacheDependency 使缓存条目无效数据库引发通知,但我不知道它可以引发应用程序本身消耗的任何事件(无论如何这都没有用,因为二级缓存不适用于整个实体)。

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

You need database-level notifications/events for this. That is, the database engine has to provide notifications. For example, SQL Server has this feature. NHibernate runs on the application, so all it could potentially do by itself is polling the database for changes (your idea of using an additional table looks like polling), and we all know that's not good. NHibernate's SysCache2 takes advantage of SqlCacheDependencies to invalidate cache entries when the database raises a notification, but I'm not aware that it can raise any events to be consumed by the app itself (which wouldn't be useful anyway, since 2nd-level caches don't work with whole entities).

Another possible way to implement this would be having a NHibernate event listener place a broadcast message on a bus after any updates, then each application instance would receive this message and re-fetch from database accordingly.

风吹雪碎 2024-10-09 12:16:40

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

为了检测数据库更新,我使用了System.IO.FileSystemWatcher。请参阅示例代码 在我对我自己的类似问题的回答中。另外,请查看同一问题的另一个答案,其中建议使用 NHibernate Interceptors

我还将数据库延迟加载到网格中。每当 FileSystemWatcher 检测到数据库已更新时,我都会调用以下条件查询,并将其返回的新记录添加到 BindingList(我的网格的数据源)中。 (我只是将新记录的最高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;
        }
    }

I had to solve some similar issues on my current SQLite Fluent NHibernate project.

For detecting database updates, I used a System.IO.FileSystemWatcher. See the sample code in my answer to my own, similar, question. Also, take a look at another answer to the same question, which suggested using NHibernate Interceptors.

I also lazy load my DB into a grid. Whenever the FileSystemWatcher detects the DB has been updated, I call the following Criteria Query, and add the new records that it returns to the BindingList that is the DataSource for my grid. (I just save the highest ID of the new records in a private variable)

    /// <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;
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文