1

对于我对项目所做的每个修订,我都有一个 int 列。我想获取该项目的最后一个修订号并将其加一并将其保存到我正在制作的这个新修订版中。

我有点担心我会遇到一个问题,即同一项目同时被修订,突然之间我得到了两个相同编号的修订。

例子

Item1  Revision 1
Item1  Revision 2
Item2  Revision 1
Item2  Revision 2
Item3  Revision 1

以上可能已经在我的数据库中。现在我想向 Item1 添加另一个修订。它应该是修订版“3”。

我想发现第 1 项的最后一个修订版是“2”,然后用它来确定山雀应该是修订版“3”。

尽管我担心多个人会开始修订第 1 项并大约在同一时间提交,并且我会为所有 3 人修订第 1 项的所有 3 人重新获得修订 2,我最终会得到

Item1 Revision 1
Item1 Revision 2
Item1 Revision 3
Item1 Revision 3 (should be 4)
4

2 回答 2

1

编辑:1)如果更新同一行

NHibernate 有一个特性:VersionorTimestamp属性和围绕它的强大管理。尝试在这里阅读:何时使用 Nhibernate ?更多细节。提炼

...实体实例有一个版本,可以是数字或时间戳。Hibernate 在对象被修改时增加它的版本,自动比较版本,如果检测到冲突则抛出异常。因此,您将此版本属性添加到所有持久实体类以启用乐观锁定。...版本号只是一个计数器值——它没有任何有用的语义值。

NHibernate 文档:

因此,当您使用版本时,您将获得:

  • NHibernate 将增加版本值。
  • 如果有人试图用旧的版本值更新行,陈旧的... StaleException 将被抛出。
  • 您可以附加处理程序来解决此问题,这取决于您的代码。

然后,您可以使用更多标准功能(例如拦截器)并审核所有更新到不同表中的更改......使用当前版本号。

总结:NHibernate 中的版本控制系统并不能解决所有问题。您将获得 StaleExceptions... 并且必须处理它们。但是,您可以确定,当时只有一个版本以相同的版本号存储

编辑:2)跟踪新的变化作为新行

请根据我们的方法将此作为建议。这就是我们作为审计跟踪系统实施变更的方式

业务对象(例如 IAuditable)定义为:

public class Article : IAuditable
{
  public virtual int ID { get; set; }
  public virtual string Text { get; set; }
  ...
  // if possible to move it to base for more Business Objects
  // public virtual IList<IHistory> History { get; set; }

  public virtual IList<ArticleHistory> History { get; set; }
}

每当有更新时,都会更新 Article 自身,并创建新的 ArticleHistory 实例。使用 HiLo 生成器作为其 ID,即使在网络农场中也能正确插入。

这种方法允许使用最新的文章实例,提高性能(历史在单独的表中)并支持 AOP(通过注入 AuditAOPFilter 打开/关闭历史跟踪。仅在细节上我们加载历史集合。

这是一个建议。我可以理解这不适合您的场景(并且不回答问题)。

于 2013-02-07T05:22:26.940 回答
0

在主键和修订号的组合上创建唯一键。这至少可以防止数据库中的重复。

剩下的问题是,如果您希望这种并行编辑经常发生 - 如果是这样,您可能希望添加一些机制来更早地检测它以节省用户时间。一种方法是对原始行使用悲观锁定。

于 2013-02-07T07:50:26.280 回答