2011-10-06 25 views
2

有两个PersonDTO类和我使用NHibernate的保存这些对象。就像我有一个用户一样,没有问题,只要另一个用户要更新另一个用户正在更新的对象。那么两者都可以更新同一个对象,并且由于它由另一个用户更新,所以更改将会丢失。我如何实现并发NHibernate的

为了实现cuncurrency我使用了两种方式,他们都面临着问题。

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

第一种方法是用伟大的工作任何问题,但不幸的是,我没有足够的授权给负载完全与它的依赖。所以我必须使用第二种方法。

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

请看下面的代码

负载的人通过ID

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

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

person.Version = dto.Version 

设置在更新过程中NHibernate的传递旧值到SQL和我不并发性错误的脸。

我该怎么做才能以这种方式实现并发。 任何帮助appriciated。

+0

你有没有配置Person.Version财产版本场你的映射? –

+0

当然可以。第一种解决方案工作正确,但第二种方法是一个问题。 – Ehsan

+0

我不明白这个问题。如果你在你的对象上正确配置了版本控制,NH应该为你处理并发冲突......? 你能再细说一下吗? –

回答

1

据我了解你的问题,我想您有其吸气工作正常,但是当你试图设置它,你的脸有问题的,如果是这样,那么请检查以下注意事项场

  • 检查您版本字段是不是只读
  • 检查它是否有公共二传手不是私人一个
  • 检查一下您是否需要在您的映射特性
  • 检查什么是你构造发生的事情,当你使用GetByID方法

提供,如果这些观点的详细信息未提高没帮你

+0

不是我的问题是另一回事。加载对象时,我使用Nhibernate,保留对象的原始版本,但在使用构造函数时,此对象是暂时的,并且允许第一次设置版本字段。 – Ehsan

+0

@ehsanzeynali由于你的对象是**瞬态**和Nhibernate第一次设置它的**版本**字段,实际上你不能改变版本,直到更新过程,所以使用** GetByID **在我看来是毫无意义的。 –

+0

设置版本字段在操作中是允许的,但实际上并不适用。那么为什么设置允许。为什么版本字段不是私人的? – Ehsan

2

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

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

+0

我读到这文章,但我的问题是另一回事。我写评论。 – Ehsan

1

您的代码应该像下面

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

地图Person.version财产上的映射文件版本字段。像下面

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

一旦启用显示SQL和运行它

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

和更新代码,你应该看到类似以下

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

没有我的问题是另一回事。加载对象时,我使用Nhibernate,保留对象的原始版本,但在使用构造函数时,此对象是暂时的,并且允许第一次设置版本字段。设置版本字段在操作中是允许的,但实际上并不适用。那么为什么设置允许。为什么版本字段不是私人的? – Ehsan