1. 程式人生 > >Oracle Sequence使用注意

Oracle Sequence使用注意

情況大概是這樣:專案中使用Oracle的Sequence來生成流水號,並設定cache為20,。然後通過測試環節後交付給客戶上生產。然後一段時間後,客戶反饋說有bug。拿到生產環境的資料庫dump部署後一查,發現相關資料確實有問題:

1)如果按照流水號從小到大,資料入庫時間不連續,並且流水號跳號,比如從1000、1001直接到1020,中間丟了1002~1019。

2)如果按照資料入庫時間從小到大,流水號跳號並且是穿插,比如從1000、1001直接到1020,然後是1002,、1003、然後是1021。

通過查詢資料以及結合生產環境的Oracle使用RAC推斷,上面的2)才是資料入庫的方式:

RAC有2個節點,節點1和節點2。假設某個表的Sequence從1000開始,cache20個。一開始請求從節點1拿流水號,使得節點1快取20個流水號(1000~1019),在使用了1000、1001之後,請求被切到節點2,然後節點2也快取20個流水號(1020~1039),在使用了1020之後請求再被切回節點1,繼續使用接下來的1002和1003,再切回節點2使用1021。如此造成流水號穿插跳號情形。因此如果我們的sql裡面對流水號有一些max,min,>=、<=等等型別的操作,那麼可能就會有問題。

相關Oracle資料也介紹,Sequence只能保證唯一,不能保證連續(即可能跳號,比如share_pool被刷或宕機後,原cache的流水號將丟失。還有就是事務回滾也會導致流水號跳號)。

而我這裡遇到的場景要特殊,是穿插跳號,而不是單向跳號,情況更嚴重。

解決:

1)對於業務流水號(就是那種需要顯示出來給客戶看的,比如XXX編碼),並且要求嚴格連續而且唯一的那種,還是自定義流水號生成器吧。

2)如果只是資料流水號,可以修改Sequence為nocache,這樣能保證單向唯一,但還不能保證連續(因為事務回滾)。我們就是採取這種方式,因為底層sql大部分都是採用Sequence,如果全部改掉,工作量大,何況已上生產,採用折中方案。如果是處於開發階段,可以考慮全部採用1)中說的自定義流水號生成器。

總結:

Q:為什麼問題到了生產才出現?

A:

--我們在測試環節並沒有真正完全模擬生產環境,沒有部署RAC。

--對Sequence,前期基本就是知道怎麼用,而沒有真正去了解過使用的注意事項。

記錄下來,避免重複踩到一個坑裡面。