如何在NHibernate中实现并发

时间:2011-10-06 14:45:33

标签: c# nhibernate mvvm concurrency

我有两个 Person PersonDTO 类,我正在使用 NHibernate 来保存这些对象。因为我有一个用户没有问题,并且一旦另一个用户要更新另一个用户正在更新它的对象。然后两个都可以更新同一个对象,因为它被另一个用户更新,所以更改将会丢失。

为了实现cuncurrency,我使用了两种方式来解决问题。

  • 第一个解决方案:使用人员构造函数更新对象
  • 第二种方法:使用 GetByID 方法

第一种方法可以解决任何问题,但遗憾的是,我没有足够的权限来加载 Person 及其依赖项。所以我必须使用第二种方法。

在第二种方法中,当我设置(更新)版本时,直到最后一秒,但NHibernate正在使用其旧版本,因此我的更改将不适用。

请查看以下代码

按ID加载人

person = locator.PersonRepository.GetById(dto.Id);

版本字段由新值加载。但是我需要从 PersonDTO 对象

中设置它
person.Version = dto.Version

在更新过程中,NHibernate将旧值传递给sql,我不会遇到concurreny错误。

我应该怎样做才能以这种方式实现并发。 任何帮助都是适当的。

3 个答案:

答案 0 :(得分:2)

Ayende对nHibernate支持的不同类型的并发有interesting article。如果您设置了一个版本列,那么nHibernate将自动管理版本的值,并在您尝试更新已过时的对象时抛出StaleObjectException

您可以使用此异常来通知用户或实现更复杂的自动并发解决方法。

答案 1 :(得分:1)

据我了解你的问题,我猜你有一个字段 getter 可以正常工作,但当你尝试设置时,你会遇到问题,如果是那么,请检查以下注意事项

  • 检查您的版本字段是否非Readonly
  • 检查是否有公共设置器而不是私有
  • 检查映射器
  • 中是否需要属性
  • 检查构造函数中使用 GetByID 方法时未引发的内容

如果这些想法对您没有帮助,请提供更多信息

答案 2 :(得分:1)

您的代码应该如下

public class Person
{
    public virtual DateTime Version { get; set; }
    public virtual string FirstName { get; set; }
    .
}

将Person.version属性映射为Mapping文件的版本字段。

<version name="Version" column="Version" type="timestamp" unsaved-value="1/1/0001" />

并更新如下代码

var person = session.Get(personDto.Id);
person.Version = personDto.Version
person.FirstName = personDto.FirstName
session.SaveOrUpdate(person);

启用show sql并运行它后,您应该看到如下

UPDATE [Person] 
SET Version = @p0, FirstName = @p1 
WHERE PersonId = @p3 AND Version = @p4;