Oracle-11g-R2

如果序列生成的 ID 的最大目前值為 N,這是否保證所有未來行的索引 > N?

  • January 27, 2021

我正在調試一些遺留程式碼,並發現它與數據庫互動的方式可能存在缺陷。它的簡化版本如下:

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 僅用於保證有序生成。如果您使用獨占模式,則始終按順序生成序列號。

另一個潛在的問題是,如果序列達到MAXVALUECYCLE通過從最小值重新開始來設置。 NOMAXVALUE並且NOCYCLE是預設值,因此使用這樣的序列的人會以這種方式創建序列是非常不尋常的。

正如已經指出的,您可以從序列中獲取價值,並在送出數據之前等待一個小時。送出後,您將擁有一個 id 比當時立即送出的其他記錄低得多的記錄。

我建議要麼

  1. 添加一列將行標記為正在處理並僅刪除這些行,或
  2. 使用ORA_ROWSCN而不是Id列,因為它表示送出時間戳(對於您的情況,您必須使用創建表ROWDEPENDENCIES,否則 ROWSCN 被分配給整個塊,而不是每一行)。

T1 送出後對 R 行 ORA_ROWSCN 的查詢將返回一個低於 T2 送出後返回的值

那就是您正在尋找的保證…

引用自:https://dba.stackexchange.com/questions/284039