NHibernate HiLo的解释

我很努力让我的头脑如何HiLo生成器在NHibernate中工作。 我读过这里的解释,它使事情变得更加清晰。

我的理解是,每个SessionFactory都会从数据库中检索到较高的值。 这可以提高性能,因为我们可以在不碰到数据库的情况下访问ID。

上述链接的解释还说明:

例如,假设您有一个“高”序列,当前值为35,“低”数字在0-1023范围内。 然后,客户端可以将序列增加到36(对于其他客户端在使用35时能够生成密钥),并且知道35/0,35/1,35/2,35/3 ... 35/1023的密钥是全部可用。

这在Web应用程序中如何工作,因为我不只有一个SessionFactory,因此只有一个Hi值。 这是否意味着在断开连接的应用程序中,实体表中可能会出现重复(低)ID?

在我的测试中,我使用了这些设置:

<id name="Id" unsaved-value="0">
  <generator class="hilo"/>
</id>

我跑了一个测试来保存100个对象。 我表中的ID从32768 - 32868开始。下一个hi值增加到2.然后我再次运行我的测试,Ids在65536 - 65636之间。

首先,为什么从32768开始而不是1,其次是为什么要从32868跳到65536?

现在我知道我的代理键应该没有任何意义,但我们确实在应用程序中使用它们。 为什么我不能让它们像SQL Server身份字段那样很好地增加。

最后可以有人给我一个关于max_lo参数如何工作的解释? 这是低价值的最大数量(我头脑中的实体标识),可以根据高价值创建吗?

这是NHibernate的一个主题,我一直在努力寻找文档。 我在行动书中阅读了整个NHibernate,但它仍然没有详细讨论它的工作原理。

谢谢Ben


我相信你的理解或多或少是正确的。 max_lo参数仅用于确定任何给定Hi值可用的Ids数量。

我最好的猜测是NHibernate的默认max_lo值是32768.因此,Hi值为1将启动您的Id值32768并运行您直到65535. Hi值为2将从65536开始并运行另一个max_lo Ids。

基本上你使用max_lo值来控制ID碎片。 对于每种情况,32768可能都不是最佳值。

然而,需要注意的是,这只能在SessionFactory的范围内使用。 如果你正在停止/启动应用程序并重新初始化SessionFactory,那么无论如何它会在启动时增加Hi值,并且你会看到你的Ids跳得很快。


查看由我的Nhibernate 3 HiLo对象生成的键,算法如下所示:(Hi * Lo)+ Hi

所以我的Hivalue在DB中为390,配置如下:

<id name="TimeclockId" column="TimeclockId" type="Int64" unsaved-value="0">
      <generator class="hilo">
        <param name="where">TableId = 1</param>
        <param name="table">HiValue</param>
        <param name="column">NextValue</param>
        <param name="max_lo">10</param>
      </generator>
    </id>

我重新启动我的应用程序池并获得(390 * 10)+ 390 = 4290,范围是4290 - 4300。

这就是为什么你在主键上出现看似奇怪的间隙的原因,因为从391的hi值生成的下一个键是4301,范围是4301-4311。


NHibernate 3.1.1使用HiLo来生成ID

if (lo > maxLo)
{
    long hival = <GetNextHiFromDB>
    lo = hival == 0 ? 1 : 0;
    hi = hival * (this.maxLo + 1L);
}
long result = hi + lo;
lo++;
return result;

在NHibernate配置里面你指定了maxLo。 如果maxLo设置为100,则每个hi值将得到101个ID。

链接地址: http://www.djcxy.com/p/19113.html

上一篇: Explanation of NHibernate HiLo

下一篇: NHibernate and hilo generator: how to design key