sequence是用來在多用戶環境下產生唯一整數的數據庫對象。序列產生器順序生成數字,它可用于自動生成主鍵值,并能協調多行或者多表的主鍵操
作。沒有sequence,順序的值只能靠編寫程序來生成。先找出最近產生的值然后自增長。這種方法要求一個事務級別的鎖,這將導致在多用戶并發操作的環
境下,必須有人等待下一個主鍵值的產生。而且此方法很容易產生主鍵沖突的錯誤,如下圖:
time a......trans1 begin.........................................................
|
取max value=5
|
time b...... max value+1=6........trans2 begin.....................
| |
other action max value=5
| |
time c..... commit; ...................max value+1=6................
|
commt(ora-00001)
如上圖,事務2會報主鍵沖突的錯誤,而再刷新一下頁面(再執行一邊程序),可能就正常了。
還有一個問題,那就是完成生成主鍵的程序
(一般情況包含plsql塊)本身對于并發調用也是一個瓶頸,因為這樣的程序段往往是提供給好多程序去調用,如果代碼端寫的不夠優化(比如沒有使用邦定變
量等等),或者此代碼段存在問題,那么它所影響的是系統的全局。我們應該提倡開發人員使用sequence。sequence消除了序列化問題,而且改善
了應用的并發能力。
創建sequence
sequence的命名最重要的是要統一,命名規則是次要的。
CREATE SEQUENCE emp_sequence
INCREMENT BY 1
START WITH 1
NOMAXVALUE
NOCYCLE
CACHE 10;
這
里需要重點說明的是cache參數,它是為了應對并發訪問的。cache參數告訴oracle預先分配一個sequence
numbers的集合,并且保留在內存中,以便sequence
number能夠被快速的訪問。這個內存的大小就是cache所指定的大小,當多個用戶同時訪問一個sequence的時候,是在oracle
SGA中讀取sequence當前的合理數值,如果并發訪問太大,cache的大小不夠,那么就會產生sequence
cache相關的等待(enq: SQ - contention),影響系統性能。
既然cache涉及到了內存,那么就會想到oracle實例恢復的問題。如果數據庫shutdown abort,sequence會如何呢?當然會有問題,sequence number保存在內存里的但是沒有被應用到表中的會丟失!
修改sequence
除了修改sequence的starting number,你什么都能改,如果想改starting number,只能先drop然后create。
ALTER SEQUENCE emp_sequence
INCREMENT BY 10
MAXVALUE 10000
CYCLE
CACHE 20;
修
改很有用,最典型的情況是“需要把sequence 的current value改大一點,避免程序報錯!”。你就可以看看current
value是多少,然后修改increment by 足夠大的值,然后執行.nextval,最后別忘了再將increnent
by改成原來的值,還要注意做這些工作的前提是當前沒有人用此sequence。
使用 sequence
CURRVAL 和 NEXTVAL 能夠在以下情況使用:
insert的values字句、select中的select列表、update中的set字句
CURRVAL 和 NEXTVAL 不能夠在以下情況使用:
子查詢、視圖和實體化視圖的查詢、帶distinct的select語句、帶
group by和order
by的select語句、帶union或intersect或minus的select語句、select中的where字句、create
table與alter table中的default值、check約束條件。
刪除sequence
drop sequence seq_a;
當刪除sequence后,對應它的同義詞會被保留,但是引用時會報錯。
oracle rac環境中的sequence
oracle為了在rac環境下為了sequence的一致性,使用了三種鎖:row cache lock、SQ鎖、SV鎖。
row cache lock的目的是在sequence指定nocache的情況下調用sequence.nextval過程中保證序列的順序性;
SQ鎖是應用于指定了cache+noorder的情況下調用sequence.nextval過程中。
SV
鎖(dfs lock handel) 是調用sequence.nextval期間擁有的鎖。前提是創建sequence時指定了cache
和order屬性 (cache+order)。order參數的目的是為了在RAC上節點之間生成sequence的順序得到保障。
創建sequence賦予的cache值較小時,有enq:sq-contention等待增加的趨勢。
cache的缺省值是20.因此創建并發訪問多的sequence時,cacheh值應取大一些。否則會發生enq:sq-contention等待事件。
rac上創建sequence時,如果指定了cache大小而賦予noorder屬性,則各節點將會把不同范圍的sequence值cache到內
存上。若兩個節點之間都必須通過依次遞增方式使用sequence,必須賦予如下的order屬性(一般不需要這樣做)"sql> create
sequence seq_b cache 100
order"。如果是已賦予了cache+order屬性的sequence,oracle使用SV鎖進行同步。SV鎖爭用問題發生時的解決方法與sq鎖
的情況相同,就是將cache 值進行適當調整。
在RAC多節點環境下,Sequence的Cache屬性對性能的影響很大。應該盡量賦予cache+noorder屬性,并要給予足夠的
cache值。如果需要保障順序,必須賦予cache+order屬性。但這時為了保障順序,實例之間需要不斷的交換數據。因此性能稍差。