NHibernate:修改两个会话中实体的不同字段

NHibernate:修改两个会话中实体的不同字段,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我有一个具有多个字段的实体。可以对其执行两种类型的操作:长操作(通常由用户启动)和短操作(由系统定期运行)。这两个选项都会更新实体,但它们涉及不同的字段 不能有两个并发的长操作或两个并发的短操作。但是,系统可能会在长操作正在进行时安排短操作,并且这两个操作应该同时执行。由于它们涉及不同的领域,我相信这应该是可能的 我认为NHibernate的更改跟踪应该做到这一点——即,如果一个会话加载一个实体并更新一些字段,而另一个会话加载同一个实体并更新不同的字段,那么两者不会发生冲突。然而,我觉得我不应该

我有一个具有多个字段的实体。可以对其执行两种类型的操作:长操作(通常由用户启动)和短操作(由系统定期运行)。这两个选项都会更新实体,但它们涉及不同的字段

不能有两个并发的长操作或两个并发的短操作。但是,系统可能会在长操作正在进行时安排短操作,并且这两个操作应该同时执行。由于它们涉及不同的领域,我相信这应该是可能的

我认为NHibernate的更改跟踪应该做到这一点——即,如果一个会话加载一个实体并更新一些字段,而另一个会话加载同一个实体并更新不同的字段,那么两者不会发生冲突。然而,我觉得我不应该依赖它,因为它听起来像是一个“优化”或“实现细节”。我倾向于将更改跟踪视为减少数据库流量的优化,我不希望系统的功能依赖于它。此外,如果我决定为这个实体实现乐观并发,那么我就有可能得到一个StaleObjectException,即使我可以保证没有实际的冲突

实现这一目标的最佳方式是什么?我应该把实体一分为二吗?这是否会影响数据库的一致性(例如,如果数据库中只有实体的“一半”呢)?我可以使用NHibernate显式地只设置实体的单个字段吗?我不想依靠变更跟踪来实现功能,这是错的吗


如果重要的话,我使用的是Fluent NHibernate。

您可以使用
动态更新
映射实体

  • 动态更新
    (可选,默认为false):指定应在运行时生成更新SQL,并仅包含值已更改的列
如果启用动态更新,则可以选择乐观锁定策略:

  • version
    检查版本/时间戳列
  • all
    检查所有列
  • dirty
    检查更改的列
  • none
    不要使用乐观锁定

更多信息。

谢谢您的建议。不过,这不是仍然依赖于更改跟踪“优化”吗?我担心的是,为了优化,我一直认为更改跟踪是减少数据库查询的一种方法。我有一种不舒服的感觉,依赖它来满足功能需求(即允许两个操作同时运行)。分离这两个操作所处理的数据不是更明确(因此不容易因意外更改而中断)吗?@telewin我仍然看不到分离实体的好处。动态更新只会更新已更改的属性,而不管其中发生了什么更改,并且根据您的模型,这两个操作不会与另一个操作重叠,因此我仍然看不到问题。:)我担心的是,人们(即其他开发人员)可能会将更改跟踪视为一种优化,这意味着可以在不影响功能的情况下关闭它。如果您将锁定策略从“脏”更改为“版本”,并且事情停止工作,您会感到惊讶吗?分离实体可以防止这种情况发生。或者您认为锁定策略应该被视为功能的一部分,因此这是可以接受的?当然,乐观锁定和悲观锁定之间的选择是功能的一部分(影响异常等)。@televin我确实认为锁定策略应该。但是,NHibernate的主要开发人员表示,“我们强烈建议您使用版本/时间戳列对NHibernate进行乐观锁定。这是性能方面的最佳策略,也是正确处理会话外所做修改的唯一策略(即使用ISession.Update()时)。请记住,无论采用何种未保存的值策略,版本或时间戳属性都不应为null,否则实例将被检测为瞬态。“我不确定我是否遵循此方法-版本或时间戳都不适用于我的情况。你是说脏衣服不应该用吗?