Oracle 數(shù)據(jù)庫 Sequence Pre-allocation

事件背景:

之前我手里的一個項目需要升級weblogic從11g到12c悴晰,要將Toplink轉(zhuǎn)化為Eclipselink,然后當(dāng)時遇到一個方法:databaseLogin.setSequencePreallocationSize(1);這個方法已經(jīng)無法使用庸论,就先將他注釋掉了薇溃。然后在測試中發(fā)現(xiàn)啟動后運行一段時間搜锰,DB就會報出主鍵沖突的錯誤。經(jīng)過排查發(fā)現(xiàn)每次重新啟動Server身坐,各個數(shù)據(jù)庫表的插入數(shù)據(jù)的id幾乎都會是原來最大id減去50的值囊陡,使得再插入新的數(shù)據(jù)會有id相同的情況。而且這種情況是周期性的掀亥,每增加50個id撞反,就會將id減去50重新處理。

相關(guān)知識:

首先搪花,什么是Sequence:Sequence是數(shù)據(jù)中一個特殊存放等差數(shù)列的表遏片,該表受數(shù)據(jù)庫系統(tǒng)控制,任何時候數(shù)據(jù)庫系統(tǒng)都可以根據(jù)當(dāng)前記錄數(shù)大小加上步長來獲取到該表下一條記錄應(yīng)該是多少撮竿,這個表沒有實際意義吮便,常常用來做主鍵用。以下是他的表結(jié)構(gòu):


SequenceTable表結(jié)構(gòu)

increment_by(增長間隔),max_value (最大值),min_value (最小值),cache (制定存入緩存序列值的個數(shù)) ,last_number (當(dāng)前可取的最后一個number)

其中重點說一下increment_by幢踏,每當(dāng)表將已有的Sequence用完之后髓需,將會預(yù)加載的sequence大小。然后Last_number = last_number + increment_by房蝉。之后Sequence就會從預(yù)加載的這一塊Sequence的第一個開始讀僚匆。

開發(fā)中用到的相關(guān)方法:

先說明一下為什么會產(chǎn)生背景中介紹的那樣的問題。首先看一下EclipseLink在試圖取得下一段可使用Sequence所使用的方法:

protected Vector createVector(Number sequence, String seqName, int size) {

? ? ? ? long nextSequence = sequence.longValue();

? ? ? ? Vector sequencesForName = new Vector(size);

? ? ? ? nextSequence -= (long)size;

? ? ? ? if(nextSequence < -1L) {

? ? ? ? ? ? throw ValidationException.sequenceSetupIncorrectly(seqName);

? ? ? ? } else {

? ? ? ? ? ? for(int index = size; index > 0; --index) {

? ? ? ? ? ? ? ? ++nextSequence;

? ? ? ? ? ? ? ? sequencesForName.add(Long.valueOf(nextSequence));

? ? ? ? ? ? }

? ? ? ? ? ? return sequencesForName;

? ? ? ? }

? ? }

SequenceForName是接下來所能使用的Sequence列表搭幻,從代碼中可以看出咧擂,取得的sequence區(qū)間是 nextSequence - size ~?nextSequence。sequece得到的值和DB中sequence table相關(guān)檀蹋,如上圖我們的設(shè)置松申,下一個要取的sequence id是最后一個id + 1,而size = 50 (之后會說明為什么=50),所以新的sequence區(qū)間相當(dāng)于后退了49個id贸桶。

然后我們看一下之前被我們注釋的方法的官方說明:

setSequencePreallocationSize

public voidsetSequencePreallocationSize(int?size)

Deprecated.use getDefaultSequence().setPreallocationSize(int) instead

OBSOLETE:

TopLink supports sequence number preallocation.

This improves the performance and concurrency of inserts by selecting new object IDs in batches and caching them on the client.

The preallocation size can be configured, and the default is 50.

By default a sequence table is used. Using a sequence table is recommended as it supports preallocation.

This MUST be 1 if native sequencing is used on Sybase, Informix, or SQL Server.

This MUST match the SEQUENCE increment if Oracle native sequencing is used.

注意最后兩行舅逸,由于我們使用了Nactive sequence(Many databases have built in support for sequencing. This can be a SEQUENCE object such as in Oracle,or a auto-incrementing column such as the IDENTITY field in Sybase. For an auto-incrementing column the preallocation size is always 1.For a SEQUENCE object the preallocation size must match the SEQUENCE objects "increment by".)所以是要主動設(shè)置這個增量size的(50 -> 1)Squence table不用做改動 (因為本來就是1)

這里有一點比較奇怪,就是如果直接使用databaseLogin.useNativeSequencing();還是會去取this.getPlatform().getDefaultSequence().getPreallocationSize() 作為Pre-allocation皇筛,就是還是會賦默認(rèn)值50... 所以我們采取的解決方案是用默認(rèn)的Sequecing并修改Pre-allocation的值:databaseLogin.setDefaultSequence(new NativeSequence(login.getPlatform().getDefaultSequence().getName(),1, login.getPlatform().getDefaultSequence().getInitialValue())); 這樣問題就解決了堡赔。

還有一點就是為什么其他的application升級eclipseLink時候沒有問題,可能是最初就用的DefaultSequencing或者使用getDefaultSequence().setPreallocationSize(int)設(shè)置的Pre-allocation吧设联,因為setSequencePreallocationSize(1) 在Toplink的時候已經(jīng)廢棄了善已。

以上就是這個問題的解決過程。其實也不用特別在升級的時候留意离例,因為EclipseLink中如果有setSequencePreallocationSize(1)這個方法會標(biāo)紅换团,這樣自然而然會用新的方法設(shè)置default值,就不會有問題了宫蛆。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末艘包,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子耀盗,更是在濱河造成了極大的恐慌想虎,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叛拷,死亡現(xiàn)場離奇詭異舌厨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)忿薇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門裙椭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人署浩,你說我怎么就攤上這事揉燃。” “怎么了筋栋?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵炊汤,是天一觀的道長。 經(jīng)常有香客問我弊攘,道長抢腐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任肴颊,我火速辦了婚禮氓栈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘婿着。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布竟宋。 她就那樣靜靜地躺著提完,像睡著了一般。 火紅的嫁衣襯著肌膚如雪丘侠。 梳的紋絲不亂的頭發(fā)上徒欣,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機(jī)與錄音蜗字,去河邊找鬼打肝。 笑死,一個胖子當(dāng)著我的面吹牛挪捕,可吹牛的內(nèi)容都是我干的粗梭。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼级零,長吁一口氣:“原來是場噩夢啊……” “哼断医!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起奏纪,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤鉴嗤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后序调,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體醉锅,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年发绢,在試婚紗的時候發(fā)現(xiàn)自己被綠了荣挨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡朴摊,死狀恐怖默垄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情甚纲,我是刑警寧澤口锭,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站介杆,受9級特大地震影響鹃操,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜春哨,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一荆隘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赴背,春花似錦椰拒、人聲如沸晶渠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽褒脯。三九已至,卻和暖如春缆毁,著一層夾襖步出監(jiān)牢的瞬間番川,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工脊框, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留颁督,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓浇雹,卻偏偏與公主長得像沉御,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子箫爷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容

  • pyspark.sql模塊 模塊上下文 Spark SQL和DataFrames的重要類: pyspark.sql...
    mpro閱讀 9,446評論 0 13
  • 又一次靜靜坐在電腦前嚷节,對著視屏那頭的你想入非非似乎不是很好呢』⒚可是看著簡單務(wù)實硫痰,黑發(fā)濃眉的你那么認(rèn)真的敲代碼做實驗...
    龍貓_田小喵閱讀 241評論 1 1
  • 這個世界,你究竟了解多少... ... 我租住的小區(qū)窜护,草發(fā)得旺盛效斑,半夜依然會有雀鳥在耳語,聲音穿透了紗窗柱徙。風(fēng)兒卷動...
    顏先生Yan閱讀 643評論 2 4
  • 在網(wǎng)易云音樂缓屠,歌曲《極樂凈土》評論下有個段子:評論者說自己是聽了無數(shù)佛經(jīng)才找到這里。不懂日文护侮,所以不知道這首歌名稱...
    寒衣霜劍閱讀 1,052評論 0 0