如何安全地将Hibernate hi / lo转换为池?

时间:2016-09-28 15:40:14

标签: java hibernate sequence

不幸的是,我用

开始了一个项目
@Id
@Generated(GenerationTime.INSERT)
@GeneratedValue(generator = "hibernate_sequence")
@GenericGenerator(
        name = "hibernate_sequence",
        strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
        parameters = {
                @Parameter(name = "increment_size", value = "100"),
                @Parameter(name = "optimizer", value = "hilo")
        })
private Integer id;
在我了解到有更好的方法之前。问题是我的hi / lo算法生成的值必须在使用之前乘以100。因此,当我在数据库中看到类似1107的序列值时,意味着值110700到110799将用于下一个ID。这使得手动添加实体非常容易出错。

所以我想将算法切换到池化或合并。为此,我需要将存储值更改为110800?丢失一些身份证明显然并不重要,但我要问的是,我需要一种万无一失的方式。

一个附带问题(诚然,以意见为基础):我应该选择合并或合并吗?

1 个答案:

答案 0 :(得分:0)

基于HiLoOptimizer.generate

的代码
std::codecvt<wchar_t, char>

在第一次运行时:

  1. 读取DB的当前值(@Override public synchronized Serializable generate(AccessCallback callback) { final GenerationState generationState = locateGenerationState( callback.getTenantIdentifier() ); if ( generationState.lastSourceValue == null ) { // first call, so initialize ourselves. we need to read the database // value and set up the 'bucket' boundaries generationState.lastSourceValue = callback.getNextValue(); while ( generationState.lastSourceValue.lt( 1 ) ) { generationState.lastSourceValue = callback.getNextValue(); } // upperLimit defines the upper end of the bucket values generationState.upperLimit = generationState.lastSourceValue.copy().multiplyBy( incrementSize ).increment(); // initialize value to the low end of the bucket generationState.value = generationState.upperLimit.copy().subtract( incrementSize ); } else if ( ! generationState.upperLimit.gt( generationState.value ) ) { generationState.lastSourceValue = callback.getNextValue(); generationState.upperLimit = generationState.lastSourceValue.copy().multiplyBy( incrementSize ).increment(); } return generationState.value.makeValueThenIncrement(); } )。请注意,回调应自动更新DB状态。对于lastSourceValue,这应该通过特定于数据库的特征的DB特定实现来完成。

  2. 代码enusres SequenceStyleGenerator&gt; = 1

  3. lastSourceValue = upperLimit * incrementSize + 1

  4. lastSourceValue = value - upperLimit = incrementSize *(incrementSize - 1)+ 1.代码确保lastSourceValue &gt; = 1,以便(lastSourceValue - 1)仍然不是负数且lastSourceValue至少为1

  5. value作为第一个生成的ID

  6. 返回

    因此,如果您的数据库中的序列存储1234,那么保证尚未使用的第一个ID(即使不是预先汇集的)是123 3 01 =(1234 - 1)* 100 + 1。

    悲观模式 :除了所有的数学和逻辑之外,为什么不添加value更多只是为了安全起见?