NHibernate HiLo的说明

Ben*_*ter 34 .net nhibernate

我很难理解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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

最后有人能给我一个max_lo参数如何工作的解释吗?这是可以针对高值创建的最小低值(我脑中的实体ID)的数量吗?

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

谢谢Ben

Chr*_*los 21

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

我最好的猜测是NHibernate的默认max_lo值是32768.因此,Hi值1将在32768处开始你的ID并向右运行到65535. Hi值2将从65536开始并运行另一个max_lo ID.

基本上,您使用max_lo值来控制Id碎片.32768可能不是每种情况的最佳值.

但需要注意的是,这仅适用于SessionFactory的范围.如果你正在停止/启动你的应用程序并重新初始化SessionFactory,它会在启动时增加Hi值,你会看到你的Ids跳得很快.

  • 默认的max_lo值是java short.MAX_VALUE == 2 ^ 15-1 = 32767 (3认同)

gt1*_*124 9

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

所以我在数据库中的Hivalue为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>
Run Code Online (Sandbox Code Playgroud)

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

这就是为什么你的主键中看起来很奇怪的原因,因为hi值为391的下一个生成键是4301,范围是4301-4311.