使用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應用性能優化)