如果序列生成的 ID 的最大目前值為 N,這是否保證所有未來行的索引 > N?
我正在調試一些遺留程式碼,並發現它與數據庫互動的方式可能存在缺陷。它的簡化版本如下:
TableA 充當隊列。它以相當高的速度從多個使用者/會話中插入數據。除了我要描述的那個之外,從來沒有任何更新或刪除。該表有一個整數 ID,該 ID 由表上的“插入前”觸發器填充,該觸發器從序列中提取值。
消費者應用程序每次重複選擇整個表,處理數據,並儲存結果集的最大索引值。然後執行
DELETE FROM TableA WHERE id<=:maxSelectedID
**我的問題是,這是刪除之前選擇的所有數據(並且僅刪除該數據)的可靠方法嗎?**我覺得這張表上的插入量很可能在較低的 ID 之前送出(因此可以選擇)較高的 ID。在這種情況下,較低的可能會在沒有被選中的情況下被刪除(或者如果我們幸運的話,它也會錯過在下一次選擇中擷取的刪除)。
如果數據庫在 RAC 集群上執行,那麼集群中的每個節點都會有一個單獨的序列記憶體。這將導致返回的值亂序,除非該序列是使用
ORDER
指定的(即CREATE SEQUENCE seq_foo START WITH 1 ORDER
)創建的。如果數據庫在獨立實例上執行,序列號將始終按順序生成。如果您出於功能原因依賴此行為,我會很迂腐,
ORDER
甚至在獨立數據庫上創建序列時也會指定。但沒有必要這樣做。從文件
如果您使用 Oracle Real Application Clusters,則 ORDER 僅用於保證有序生成。如果您使用獨占模式,則始終按順序生成序列號。
另一個潛在的問題是,如果序列達到
MAXVALUE
並CYCLE
通過從最小值重新開始來設置。NOMAXVALUE
並且NOCYCLE
是預設值,因此使用這樣的序列的人會以這種方式創建序列是非常不尋常的。
正如已經指出的,您可以從序列中獲取價值,並在送出數據之前等待一個小時。送出後,您將擁有一個 id 比當時立即送出的其他記錄低得多的記錄。
我建議要麼
- 添加一列將行標記為正在處理並僅刪除這些行,或
- 使用ORA_ROWSCN而不是Id列,因為它表示送出時間戳(對於您的情況,您必須使用創建表
ROWDEPENDENCIES
,否則 ROWSCN 被分配給整個塊,而不是每一行)。T1 送出後對 R 行 ORA_ROWSCN 的查詢將返回一個低於 T2 送出後返回的值
那就是您正在尋找的保證…