在NHibernate中的会话之外的乐观并发 [英] Optimistic concurrency out of session in NHibernate

查看:125
本文介绍了在NHibernate中的会话之外的乐观并发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在网络应用程序中以有意义的方式在NHibernate中实现optimisitc并发时遇到问题。以下是所需的场景:

I'm having trouble implementing optimisitc concurrency in NHibernate in a meaningful way in a web application. Here is the desired scenario:


  1. 用户A打开一个表单以编辑记录

  2. 打开相同的表单以编辑相同的记录

  3. 用户A保存他们的数据

  4. 用户B尝试保存他们的数据,已更新。

  1. User A opens a form to edit a record
  2. User B opens the same form to edit the same record
  3. User A saves their data
  4. User B tries to save their data but get a warning that the data has been updated.

常见情况。这是更新代码和实体映射文件:

A common scenario. Here is the update code and entity mapping file:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Entities" assembly="Domain">
    <class name="Record" />
        <id name="Id" column="Id" type="long">
            <generator class="identity"/>
        </id>
        <version name="Version" column="Version" type="datetime" />
        <property name="Description" column="`Description`" type="string" />
    </class>
</hibernate-mapping>

public void Edit(int id, string description, DateTime version)
{
    using (var session = sessionFactory.OpenSession())
    using (var tx = session.BeginTransaction())
    {
  var record = session.Get<Record>(id);
  record.Version = version;
        record.Description = description;
        session.Update(record);
  tx.Commit();
    }
}

用户打开表单时加载版本值并存储在隐藏字段中。我希望NHibernate会尝试从WHERE子句中的表单更新版本,而是使用它刚刚在会话中加载的值。

The version value is loaded when the user opens the form and is stored in a hidden field. I was hoping NHibernate would try to update with the version from the form in the WHERE clause, but instead it uses the value it has just loaded in the session.

其他我已经阅读的东西告诉我,我应该manuall比较值,并且(例如)如果加载一个较新的版本抛出异常。但我不能相信有一个更好的方法。

Other things I have read tell me that I should manuall compare values, and (for example) throw an exception if it loads a newer version. But I can't believe there is a better way.

在我看来,NHibernate的并发控制仅在同一个会话中有用,因此在基于Web的应用程序上的陈旧表单数据时完全无用。

It seems to me that NHibernate's concurrency controls are only useful in the same session, and therefore completely useless when it comes to stale form data on web based applications.

我想能够根据用户最初加载时的表单中的内容手动设置版本。这可能吗?

I want to be able to manually set the version based on what was in the form when the user originally loaded it. Is this possible? Or am I missing something here?

推荐答案

我知道这是一个老问题,但我会离开我常用的方法。

I know this is an old question, but I'll leave my usual approach here.

使用ORM时,这是一个已知的问题。 NHibernate和Entity Framework都会遇到这个问题,因为ORM正在内部跟踪版本值,而不是使用属性返回的那个。与EF不同,你可以复制 byte [ ] 的值使用 Array.Copy ,在NHibernate我通常从实体驱逐的实体,然后进行更新,这指示NHibernate你是更新现有实体,但他将使用您刚刚分配的版本开始跟踪。

This is a know "problem" when using ORMs. Both NHibernate and Entity Framework suffer this "problem"", and it happens because the ORM is tracking internally the version value, not using the one returned by the property. Unlike EF, where you can copy the byte[] values using Array.Copy, in NHibernate I usually evict the entity from the session and then make the update, which indicates to NHibernate that you are updating an existing entity but he will start tracking using the Version you just assigned.

以下是您的代码片段:

public void Edit(int id, string description, DateTime version)
{
    using (var session = sessionFactory.OpenSession())
    using (var tx = session.BeginTransaction())
    {
        var record = session.Get<Record>(id);
        record.Version = version;
        record.Description = description;

        session.Evict(record);  //  evict the object from the session
        session.Update(record); //  NHibernate will attach the object, and will use your version

        tx.Commit();
    }
}

如果你使用我通常在我的模型类(示例),您可以轻松创建一些扩展方法,使人们更难忘记。

If you use interfaces like I usually do in my model classes (example), you can easily create some extension method, making it harder for people to forget.

据我所知,我没有发现这个方法的任何问题,但让我知道,如果你检测到任何。

To my knowledge, I haven't found any issues with this approach, but let me know if you detect any.

这篇关于在NHibernate中的会话之外的乐观并发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆