我有一個專案,它的結構是 java ee 7。我使用 hibernate 作為 ORM,我的資料庫是 Oracle。
我將@SequenceGeneratorallocationSize = 1 用于我的物體的 id 和@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq"). 我在 Oracle 中的資料庫序列快取 = 1000。但是當我在資料庫中保留兩條記錄時,第一條記錄的 id 比第二條記錄舊,即使在一天之后并且 id 不是連續的。
我該如何解決這個問題,我的問題是什么?
uj5u.com熱心網友回復:
由于您使用的是 11g(一個非常舊的版本,因此您的公司應該盡快考慮升級),因此必須通過 RAC 選項來平衡性能和完整性差距。
你有兩個選擇noordervsorder
create sequence xxx start with 1 increment by 1 noorder|order cache xxx
實體如何協調它們對序列值的使用并避免兩個實體使用相同值的風險?
有兩種解決方案:默認noorder機制,每個實體的行為就好像它不知道其他實體一樣。另一種order選擇是,實體通過使用全域佇列不斷協商,以確定在任何時候哪個實體應該負責序列。
無序
這種無序機制的結果是每個實體將通過不同的數字范圍作業,并且實體之間不會有重疊。如果您的會話每秒登錄一次資料庫以發出對 nextval 的呼叫(并且它們每次最終都通過不同的實體進行連接),那么回傳的值似乎相當隨機地分散在“實體數 x 快取大小。” 將保證唯一性,但不會保證排序。
命令
如果您使用該order選項宣告一個序列,Oracle 將采用對值使用單個“快取”的策略,并引入一種機制來確保一次只有一個實體可以訪問和修改該快取。Oracle 通過利用其 Global Enqueue 服務來做到這一點。每當會話發出呼叫nextval,實體獲取序列快取上的獨占 SV 鎖(全域入隊),有效地表示“誰獲得了有關此序列的最新資訊——我想要控制”。以獨占模式持有 SV 鎖的一個實體是唯一可以增加快取值的實體,并且在必要時通過增加高水位來更新 seq$ 表。這意味著將再次按順序生成序列號。但是這個選項會降低性能,應該仔細考慮。
概括
如果您的交易速度很快,您可以使用 order 并測驗它的行為方式。如果你的交易不快,我會避免order一起。最好的選擇是升級到 19c(12c 已經過時了)并使用IDENTTTY COLUMNS
uj5u.com熱心網友回復:
如果每個節點上都有無序(單獨的)快取(默認):
node 1: cache values (1 - 1000)
node 2: cache values (1001 - 2000)
那么快取不能重疊值,使用的值將取決于哪個節點執行插入。這就是為什么您的序列值當前似乎無序的原因。
使用NOCACHE和/或ORDERED選項將產生序列號,但您可以預期至少會對您的應用程式產生一些性能影響,因為資料庫必須執行更多開銷來確定當前序列值,然后才能將其提供給您的 SQL 命令。如果您執行大量插入操作(如您當前的快取值 1000 所建議的那樣),減少快取大小或完全消除快取會對性能產生嚴重的負面影響。
現在假設您繼續使用快取(無論是否已訂購),請注意每次重新啟動資料庫或節點(取決于您的確切配置)時,未使用的快取值將被重繪 并丟失,并生成一個新的將創建快取。
最后,重要的是要意識到序列值(對于大多數應用程式)不是為了完美的順序而沒有間隙,或者甚至(在您的情況下)是有序的。它們只是為了獨一無二。請務必了解您的要求,如果序列的行為與您預期的不一樣,請不要猶豫:值是否必須按插入的順序排列,序列中的間隙是否會影響您的應用程式?如果答案是否定的,應用程式不會關心,那么為了性能而堅持使用你所擁有的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/335935.html
