使用hibernate 5 取序號異常狀況,DB為oracle,ID生成annotation設定如下


public class OrderDet implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO, generator="OrderDetSeq")
    @SequenceGenerator(name="OrderDetSeq", sequenceName="ORDERDET_SEQ")
    @Column(name="ID")
    private BigInteger id;

    public BigInteger getId() {
        return id;
    }

    public void setId(BigInteger id) {
        this.id = id;
    }
}

 

例如:DB SEQ為100,預期取出為101 (SEQ.nextval),但實際為60

這個問題在hibernate 4沒遇到,查了一下主要是以下原因

生成器演算法的調整(V4 to V5):
(old)   hi/lo: it uses the hi/lo algorithm and it’s equivalent to the original seqhilo generator.
(new) pooled: This optimizer uses a hi/lo optimization strategy, but the current in-memory identifiers highest boundary is extracted from an actual database sequence value.

hibernate 5會產生一個生成池供程式使用,避免多次去讀取DB,當池內數值用完,再去DB取一段SEQ回來(DB.SEQ會向後推一段空間),
預設取值區段為50,可以透過allocationSize值去調整
EX:

@SequenceGenerator(name="OrderDetSeq", sequenceName="ORDERDET_SEQ", allocationSize=20)
//調為20

pool的使用當系統每次重起會清空池,所以可能造成實際使用的序號被跳躍的狀況,因為中間的號碼被撈去pool、但是pool又廢了
所以有人建議,如果要求要連號,可以設定allocationSize=1,但這狀況如果在事務繁忙的程式上,會產生效能問題,需要注意

 

另:我目前遇到的狀況是
server 1(5.1.15)
server 2(4.3)

server 1:每次取號DB號碼不會往後推
例如 DB.nextNumber = 86
server 1會取82~86出來用,然後DB.nextNumber變成87
==>HIBERNATE機制錯誤

主要是因為版本升級問題
先設定回  hibernate.id.new_generator_mappings=false
之後有找到調整的地方在補本文


 

參考網址:

https://hibernate.atlassian.net/browse/HHH-10983
https://vladmihalcea.com/the-hilo-algorithm/   (The hi/lo algorithm)
https://vladmihalcea.com/hibernate-hidden-gem-the-pooled-lo-optimizer/  (Hibernate pooled and pooled-lo identifier generators)
https://stackoverflow.com/questions/12745751/hibernate-sequencegenerator-and-allocationsize  (Hibernate, @SequenceGenerator and allocationSize)
https://www.jianshu.com/p/f0573f00eb2a (Spring/Hibernate應用性能優化)

 

    咪卡恰比 發表在 痞客邦 留言(0) 人氣()