2014-02-12 18 views

回答

1

一個Oracle序列永遠不能保證產生一個無間隙的值集合。您可以通過消除序列高速緩存(這會對性能產生負面影響)來縮小差距,但無法消除這些差距。您是否確實確定存在差距會爲您造成問題?在任何情況下,我都看到有人認爲他們想要一個沒有缺口的價值觀,正確的答案一直是生活在缺口之中,而不是處理產生無間隙序列的權衡。

如果您確實需要無間隙序列,那麼您需要強制對該表的所有更改進行序列化,以便一次只能有一個會話插入或刪除一行。這大大降低了應用程序的可伸縮性,並且例如當一個會話在用戶外出吃飯或當客戶端應用程序崩潰時迫使其他人停止工作,直到DBA出現時纔會出現各種維護問題發現並殺死違規會話。這些要比在主要價值觀上存在差距的情況差得多。

如果你真的想要走這條路,你可能想創建一個新表

CREATE TABLE my_slow_sequence( 
    table_name varchar2(30) primary key, 
    val  number 
); 

INSERT INTO my_slow_sequence('TABLE_NAME', 1); 

在,如果你想允許鍵將插入(和更新前的火災行級觸發器修改),你就需要鎖定有問題的行(確保訪問是序列化)

SELECT val 
    INTO :new.<<pk_column>> 
    FROM my_slow_sequence 
WHERE table_name = 'TABLE_NAME' 
    FOR UPDATE; 

UPDATE my_slow_sequence 
    SET val = val + 1 
WHERE table_name = 'TABLE_NAME' 

在這之後刪除火災,你需要經過同樣的過程語句級觸發器在my_slow_sequence中鎖定該行。然後,您需要掃描表以確定要設置的值val,或者需要刪除觸發器之前需要一個行級,該觸發器捕獲單個包中定義的集合中已刪除的<<pk_column>>值,您可以在語句中迭代級觸發器。

如果您希望允許更新鍵值,那麼在更新時需要一個觸發器或一組觸發器,類似於您需要處理刪除的觸發器。

試圖用觸發器處理這個問題將涉及到相當多的代碼,許多移動的部分,並會破壞系統的性能。這真的不值得。學會接受你的主鍵會有差距。

相關問題