真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

oracle鎖怎么建,oracle加鎖

oracle數(shù)據(jù)庫怎么鎖表

oracle數(shù)據(jù)庫分行級(jí)鎖和表級(jí)鎖。用select * from table-name for update完成行級(jí)鎖。用delete或update完成表級(jí)鎖。你鎖定的資源 別人會(huì)等待你的提交語句或回退語句完成以后再繼續(xù)進(jìn)行。

成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)的開發(fā),更需要了解用戶,從用戶角度來建設(shè)網(wǎng)站,獲得較好的用戶體驗(yàn)。創(chuàng)新互聯(lián)公司多年互聯(lián)網(wǎng)經(jīng)驗(yàn),見的多,溝通容易、能幫助客戶提出的運(yùn)營建議。作為成都一家網(wǎng)絡(luò)公司,打造的就是網(wǎng)站建設(shè)產(chǎn)品直銷的概念。選擇創(chuàng)新互聯(lián)公司,不只是建站,我們把建站作為產(chǎn)品,不斷的更新、完善,讓每位來訪用戶感受到浩方產(chǎn)品的價(jià)值服務(wù)。

如何給oracle數(shù)據(jù)庫添加樂觀鎖

樂觀鎖一開始也說了,就是一開始假設(shè)不會(huì)造成數(shù)據(jù)沖突,在最后提交的時(shí)候再進(jìn)行數(shù)據(jù)沖突檢測。在樂觀鎖中,我們有3種

常用的做法來實(shí)現(xiàn)。

[1]第一種就是在數(shù)據(jù)取得的時(shí)候把整個(gè)數(shù)據(jù)都copy到應(yīng)用中,在進(jìn)行提交的時(shí)候比對(duì)當(dāng)前數(shù)據(jù)庫中的數(shù)據(jù)和開始的時(shí)候更新前取得的數(shù)據(jù)。當(dāng)發(fā)現(xiàn)兩個(gè)數(shù)據(jù)一模一樣以后,就表示沒有沖突可以提交,否則則是并發(fā)沖突,需要去用業(yè)務(wù)邏輯進(jìn)行解決。

[2]第二種樂觀鎖的做法就是采用版本戳,這個(gè)在Hibernate中得到了使用。采用版本戳的話,首先需要在你有樂觀鎖的數(shù)據(jù)庫table上建立一個(gè)新的column,比如為number型,當(dāng)你數(shù)據(jù)每更新一次的時(shí)候,版本數(shù)就會(huì)往上增加1。比如同樣有2個(gè)session同樣對(duì)某條數(shù)據(jù)進(jìn)行操作。兩者都取到當(dāng)前的數(shù)據(jù)的版本號(hào)為1,當(dāng)?shù)谝粋€(gè)session進(jìn)行數(shù)據(jù)更新后,在提交的時(shí)候查看到當(dāng)前數(shù)據(jù)的版本還為1,和自己一開始取到的版本相同。就正式提交,然后把版本號(hào)增加1,這個(gè)時(shí)候當(dāng)前數(shù)據(jù)的版本為2。當(dāng)?shù)诙€(gè)session也更新了數(shù)據(jù)提交的時(shí)候,發(fā)現(xiàn)數(shù)據(jù)庫中版本為2,和一開始這個(gè)session取到的版本號(hào)不一致,就知道別人更新過此條數(shù)據(jù),這個(gè)

時(shí)候再進(jìn)行業(yè)務(wù)處理,比如整個(gè)Transaction都Rollback等等操作。在用版本戳的時(shí)候,可以在應(yīng)用程序側(cè)使用版本戳的驗(yàn)證,也可以在數(shù)據(jù)庫側(cè)采用Trigger(觸發(fā)器)來進(jìn)行驗(yàn)證。不過數(shù)據(jù)庫的Trigger的性能開銷還是比較的大,所以能在應(yīng)用側(cè)進(jìn)行驗(yàn)證的話還是推薦不用Trigger。

[3]第三種做法和第二種做法有點(diǎn)類似,就是也新增一個(gè)Table的Column,不過這次這個(gè)column是采用timestamp型,存儲(chǔ)數(shù)據(jù)最后更新的時(shí)間。在Oracle9i以后可以采用新的數(shù)據(jù)類型,也就是timestamp with time zone類型來做時(shí)間戳。這種Timestamp的數(shù)據(jù)精度在Oracle的時(shí)間類型中是最高的,精確到微秒(還沒與到納秒的級(jí)別),一般來說,加上數(shù)據(jù)庫處理時(shí)間和人的思考動(dòng)作時(shí)間,微秒級(jí)別是非常非常夠了,其實(shí)只要精確到毫秒甚至秒都應(yīng)該沒有什么問題。和剛才的版本戳類似,也是在更新提交的時(shí)候檢查當(dāng)前數(shù)據(jù)庫中數(shù)據(jù)的時(shí)間戳和自己更新前取到的時(shí)間戳進(jìn)行對(duì)比,如果一致則OK,否則就是版本沖突。如果不想把代碼寫在程序中或者由于別的原因無法把代碼寫在現(xiàn)有的程序中,也可以把這個(gè)時(shí)間戳樂觀鎖邏輯寫在Trigger或者存儲(chǔ)過程中。

Oracle中的鎖

這些是基礎(chǔ),必須掌握:鎖定的概念:鎖定是數(shù)據(jù)庫用來控制共享資源并發(fā)布訪問的機(jī)制。在多用戶環(huán)境下,多個(gè)用戶可同時(shí)訪問相同的數(shù)據(jù)。Oracle 提供鎖以確保在多用戶環(huán)境下數(shù)據(jù)的完整性和一致性。在提交或回滾事務(wù)之前,Oracle 會(huì)鎖定正被修改的數(shù)據(jù)。在用戶完成或回滾事務(wù)之后,鎖會(huì)自動(dòng)釋放。只有在提交或回滾事物之后,其他用戶才可以更新這些數(shù)據(jù)。鎖的兩種級(jí)別為:行級(jí)鎖和表級(jí)鎖。行級(jí)鎖主要用于特定的行,表級(jí)鎖主要用于整個(gè)表,下面我就行級(jí)鎖和表級(jí)鎖來個(gè)說明:行級(jí)鎖行級(jí)鎖只對(duì)用戶正在訪問的行進(jìn)行鎖定。如果該用戶正在修改某行,那么其他用戶就可以更新同一表中該行之外的數(shù)據(jù)。例如:如果用戶1正在更新Jobs 表中的第一行,則用戶2可以同時(shí)修改該表中的第二行。也就是說除了該表中的第一行,其他用戶可以修改任意行,但是第一行的數(shù)據(jù)其他用戶只能select。行級(jí)鎖是一種排他鎖,防止其他事務(wù)修改此行,但是不會(huì)阻止讀取此行的操作。在使用INSERT、UPDATE、DELETE 和SELECT…FOR UPDATE 等 語句時(shí),Oracle 會(huì)自動(dòng)應(yīng)用行級(jí)鎖鎖定。SELECT...FOR UPDATE 語句允許用戶每次選擇多行記錄進(jìn)行更新,這些記錄會(huì)被鎖定,且只能由發(fā)起查詢的用戶進(jìn)行編輯。只有在回滾或提交事務(wù)之后,鎖定才會(huì)釋放,其他用戶才可以編輯這些記錄。SELECT...FOR UPDATE 語句的語法如下: SELECT ... FOR UPDATE [OF column_list][WAIT n|NOWAIT];其中:OF 子句用于指定即將更新的列,即鎖定行上的特定列。WAIT 子句指定等待其他用戶釋放鎖的秒數(shù),防止無限期的等待?!笆褂肍OR UPDATE WAIT”子句的優(yōu)點(diǎn)如下:⒈防止無限期地等待被鎖定的行;⒉允許應(yīng)用程序中對(duì)鎖的等待時(shí)間進(jìn)行更多的控制。⒊對(duì)于交互式應(yīng)用程序非常有用,因?yàn)檫@些用戶不能等待不確定舉例:比如一個(gè)用戶在SQL PLUS下輸入這條語句:SQLSELECT * FROM order_master WHERE vencode='V002' FOR UPDATE;此時(shí)再開啟一個(gè)SQL PLUS,以相同的用戶登陸,執(zhí)行下面的命令。SQL SELECT * FROM order_master WHERE vencode='V02' FOR UPDATE WAIT 5;由于要更新的行已經(jīng)被鎖定,上述命令在等待5秒鐘之后返回,并給出如下的錯(cuò)誤信息:ERROR 位于第1行;ORA-30006;資源已被占用;執(zhí)行操作時(shí)出現(xiàn)WAIT超時(shí)。PS:再開啟的SQL PLUS 是以相同用戶登陸的,用其他用戶登陸更是不可能。表級(jí)鎖表級(jí)鎖被鎖定的表,暫時(shí)放在內(nèi)存中,不提交不進(jìn)去數(shù)據(jù)庫,也就是說,多個(gè)用戶在同一時(shí)間,同時(shí)修改同一個(gè)表的同一行時(shí),同時(shí)點(diǎn)提交,但是還是按隨機(jī)的先后被提交進(jìn)數(shù)據(jù)庫,而不是同時(shí)被提交,而是先隨機(jī)存儲(chǔ)后,被再次提交的覆蓋。表級(jí)鎖將保護(hù)表數(shù)據(jù),在事務(wù)處理過程中,表級(jí)鎖會(huì)限制對(duì)整個(gè)表的訪問??梢允褂肔OCK TABLE 語句顯示地鎖定表。表級(jí)鎖用來限制對(duì)表執(zhí)行添加、更新和刪除等修改操作。鎖定表的語法如下:LOCK TABLE table_name IN lock_mode MODE [NOWAIT];其中:lock_mode 是鎖定的模式。NOWAIT 關(guān)鍵字用于防止無限期的等待其他用戶釋放鎖。表級(jí)鎖的模式包括以下內(nèi)容:行共享 (ROW SHARE, RS): 允許其他用戶訪問和鎖定該表,但是禁止排他鎖定整個(gè)表。行共享鎖鎖定后,在同一時(shí)刻,不同用戶可以對(duì)同一個(gè)表中的被行共享鎖鎖定后的該行,具備增、刪、改、查的功能。行排他(ROW EXCLUSIVE, RX):與行共享模式相同,同時(shí)禁止其他用戶在此表上使用共享鎖。使用SELECT...FOR UPDATE 語句會(huì)在表上自動(dòng)應(yīng)用排他鎖。被行排他后,其他用戶不能同時(shí)修改該行,但是可以插入行,可以查詢?cè)撔?,其他用戶也不能再在該表上?duì)此行進(jìn)行排他。共享(SHARE, S):共享鎖將鎖定表,僅允許其他用戶查詢表中的行,但不允許插入、更新或刪除行。多個(gè)用戶可以同時(shí)在同一個(gè)表中放置共享鎖,即允許資源共享,因此得名“共享鎖”。例如,如果用戶每天都需要在結(jié)帳時(shí)更新日銷售表,則可以在更改該表時(shí)使用共享鎖以確保數(shù)據(jù)的一致性。也就是說該表只能查,其他用戶想修改表中行的數(shù)據(jù),只需要對(duì)該表進(jìn)行共享鎖。共享行排他(SHARE ROW EXCLUSIVE , SPX):執(zhí)行比共享表更多的限制。防止其他事務(wù)在表上應(yīng)用共享鎖、共享行排他鎖以及排他鎖。共享行排他是除了該行以外的其他行也不能增、刪、改。只能在此表中加低級(jí)表。要是想在該表中更改其他行的數(shù)據(jù),就只有其他用戶對(duì)該行進(jìn)行共享行排他鎖,也僅僅只能修改被這個(gè)用戶鎖定的行,而其他的行也修改不了。排他(EXCLUSIVE,E):對(duì)表執(zhí)行最大限制。除了允許其他用戶查詢?cè)摫淼挠涗?,排他鎖防止其他事務(wù)對(duì)表做任何更改或在表上應(yīng)用任何類型的鎖。這個(gè)鎖應(yīng)該叫鎖中之王,他鎖住了的話,其他用戶就只有查詢的功能了,就別想在該表中干別的事了。BTW:在能加很多鎖的表中,如果第一個(gè)用戶對(duì)該表鎖定時(shí),沒有使用“NOWAIT”語句,是需要第一個(gè)用戶對(duì)該表COMMIT或ROLLBACK 命令釋放鎖定后,其他用戶才能對(duì)該表進(jìn)行鎖定。如果其他用戶違反了該條,就會(huì)無期限的等待。。。。SQL LOCK TABLE order_mater IN SHARE MODE;而使用下面的語句就可以很少的預(yù)防這種情況的存在:SQL LOCK TBALE order_mater IN SHARE MODE NOWAIT;這是些擴(kuò)展的內(nèi)容,供大家參考

1 引言—數(shù)據(jù)庫鎖的基本概念 為了確保并發(fā)用戶在存取同一數(shù)據(jù)庫對(duì)象時(shí)的正確性(即無丟失修改、可重復(fù)讀、不讀“臟”數(shù)據(jù)),數(shù)據(jù)庫中引入了鎖機(jī)制。基本的鎖類型有兩種:排它鎖(Exclusive locks記為X鎖)和共享鎖(Share locks記為S鎖)。 排它鎖:若事務(wù)T對(duì)數(shù)據(jù)D加X鎖,則其它任何事務(wù)都不能再對(duì)D加任何類型的鎖,直至T釋放D上的X鎖;一般要求在修改數(shù)據(jù)前要向該數(shù)據(jù)加排它鎖,所以排它鎖又稱為寫鎖。 共享鎖:若事務(wù)T對(duì)數(shù)據(jù)D加S鎖,則其它事務(wù)只能對(duì)D加S鎖,而不能加X鎖,直至T釋放D上的S鎖;一般要求在讀取數(shù)據(jù)前要向該數(shù)據(jù)加共享鎖,所以共享鎖又稱為讀鎖。 2 Oracle 多粒度封鎖機(jī)制介紹 根據(jù)保護(hù)對(duì)象的不同,Oracle數(shù)據(jù)庫鎖可以分為以下幾大類: (1) DML lock(data locks,數(shù)據(jù)鎖):用于保護(hù)數(shù)據(jù)的完整性; (2) DDL lock(dictionary locks,字典鎖):用于保護(hù)數(shù)據(jù)庫對(duì)象的結(jié)構(gòu)(例如表、視圖、索引的結(jié)構(gòu)定義); (3) internal locks 和l a t c h es(內(nèi)部鎖與閂):保護(hù)內(nèi)部數(shù)據(jù)庫結(jié)構(gòu); (4) distributed locks(分布式鎖):用于OPS(并行服務(wù)器)中; (5) PCM locks(并行高速緩存管理鎖):用于OPS(并行服務(wù)器)中。 本文主要討論DML(也可稱為data locks,數(shù)據(jù)鎖)鎖。從封鎖粒度(封鎖對(duì)象的大?。┑慕嵌瓤?,Oracle DML鎖共有兩個(gè)層次,即行級(jí)鎖和表級(jí)鎖。 2.1 Oracle的TX鎖(行級(jí)鎖、事務(wù)鎖) 許多對(duì)Oracle不太了解的技術(shù)人員可能會(huì)以為每一個(gè)TX鎖代表一條被封鎖的數(shù)據(jù)行,其實(shí)不然。TX的本義是Transaction(事務(wù)),當(dāng)一個(gè)事務(wù)第一次執(zhí)行數(shù)據(jù)更改(Insert、Update、Delete)或使用SELECT… FOR UPDATE語句進(jìn)行查詢時(shí),它即獲得一個(gè)TX(事務(wù))鎖,直至該事務(wù)結(jié)束(執(zhí)行COMMIT或ROLLBACK操作)時(shí),該鎖才被釋放。所以,一個(gè)TX鎖,可以對(duì)應(yīng)多個(gè)被該事務(wù)鎖定的數(shù)據(jù)行。 在Oracle的每行數(shù)據(jù)上,都有一個(gè)標(biāo)志位來表示該行數(shù)據(jù)是否被鎖定。Oracle不象其它一些DBMS(數(shù)據(jù)庫管理系統(tǒng))那樣,建立一個(gè)鏈表來維護(hù)每一行被加鎖的數(shù)據(jù),這樣就大大減小了行級(jí)鎖的維護(hù)開銷,也在很大程度上避免了其它數(shù)據(jù)庫系統(tǒng)使用行級(jí)封鎖時(shí)經(jīng)常發(fā)生的鎖數(shù)量不夠的情況。數(shù)據(jù)行上的鎖標(biāo)志一旦被置位,就表明該行數(shù)據(jù)被加X鎖,Oracle在數(shù)據(jù)行上沒有S鎖。

2.2 TM鎖(表級(jí)鎖) 2.2.1 意向鎖的引出 表是由行組成的,當(dāng)我們向某個(gè)表加鎖時(shí),一方面需要檢查該鎖的申請(qǐng)是否與原有的表級(jí)鎖相容;另一方面,還要檢查該鎖是否與表中的每一行上的鎖相容。比如一個(gè)事務(wù)要在一個(gè)表上加S鎖,如果表中的一行已被另外的事務(wù)加了X鎖,那么該鎖的申請(qǐng)也應(yīng)被阻塞。如果表中的數(shù)據(jù)很多,逐行檢查鎖標(biāo)志的開銷將很大,系統(tǒng)的性能將會(huì)受到影響。為了解決這個(gè)問題,可以在表級(jí)引入新的鎖類型來表示其所屬行的加鎖情況,這就引出了“意向鎖”的概念。 意向鎖的含義是如果對(duì)一個(gè)結(jié)點(diǎn)加意向鎖,則說明該結(jié)點(diǎn)的下層結(jié)點(diǎn)正在被加鎖;對(duì)任一結(jié)點(diǎn)加鎖時(shí),必須先對(duì)它的上層結(jié)點(diǎn)加意向鎖。如:對(duì)表中的任一行加鎖時(shí),必須先對(duì)它所在的表加意向鎖,然后再對(duì)該行加鎖。這樣一來,事務(wù)對(duì)表加鎖時(shí),就不再需要檢查表中每行記錄的鎖標(biāo)志位了,系統(tǒng)效率得以大大提高。 2.2.2 意向鎖的類型 由兩種基本的鎖類型(S鎖、X鎖),可以自然地派生出兩種意向鎖: 意向共享鎖(Intent Share Lock,簡稱IS鎖):如果要對(duì)一個(gè)數(shù)據(jù)庫對(duì)象加S鎖,首先要對(duì)其上級(jí)結(jié)點(diǎn)加IS鎖,表示它的后裔結(jié)點(diǎn)擬(意向)加S鎖; 意向排它鎖(Intent Exclusive Lock,簡稱IX鎖):如果要對(duì)一個(gè)數(shù)據(jù)庫對(duì)象加X鎖,首先要對(duì)其上級(jí)結(jié)點(diǎn)加IX鎖,表示它的后裔結(jié)點(diǎn)擬(意向)加X鎖。 另外,基本的鎖類型(S、X)與意向鎖類型(IS、IX)之間還可以組合出新的鎖類型,理論上可以組合出4種,即:S+IS,S+IX,X+IS,X+IX,但稍加分析不難看出,實(shí)際上只有S+IX有新的意義,其它三種組合都沒有使鎖的強(qiáng)度得到提高(即:S+IS=S,X+IS=X,X+IX=X,這里的“=”指鎖的強(qiáng)度相同)。所謂鎖的強(qiáng)度是指對(duì)其它鎖的排斥程度。 這樣我們又可以引入一種新的鎖的類型。 共享意向排它鎖(Shared Intent Exclusive Lock,簡稱SIX鎖) :如果對(duì)一個(gè)數(shù)據(jù)庫對(duì)象加SIX鎖,表示對(duì)它加S鎖,再加IX鎖,即SIX=S+IX。例如:事務(wù)對(duì)某個(gè)表加SIX鎖,則表示該事務(wù)要讀整個(gè)表(所以要對(duì)該表加S鎖),同時(shí)會(huì)更新個(gè)別行(所以要對(duì)該表加IX鎖)。 這樣數(shù)據(jù)庫對(duì)象上所加的鎖類型就可能有5種:即S、X、IS、IX、SIX。 具有意向鎖的多粒度封鎖方法中任意事務(wù)T要對(duì)一個(gè)數(shù)據(jù)庫對(duì)象加鎖,必須先對(duì)它的上層結(jié)點(diǎn)加意向鎖。申請(qǐng)封鎖時(shí)應(yīng)按自上而下的次序進(jìn)行;釋放封鎖時(shí)則應(yīng)按自下而上的次序進(jìn)行;具有意向鎖的多粒度封鎖方法提高了系統(tǒng)的并發(fā)度,減少了加鎖和解鎖的開銷。 2.2.3 Oracle的TM鎖(表級(jí)鎖) Oracle的DML鎖(數(shù)據(jù)鎖)正是采用了上面提到的多粒度封鎖方法,其行級(jí)鎖雖然只有一種(即X鎖),但其TM鎖(表級(jí)鎖)類型共有5種,分別稱為共享鎖(S鎖)、排它鎖(X鎖)、行級(jí)共享鎖(RS鎖)、行級(jí)排它鎖(RX鎖)、共享行級(jí)排它鎖(SRX鎖),與上面提到的S、X、IS、IX、SIX相對(duì)應(yīng)。需要注意的是,由于Oracle在行級(jí)只提供X鎖,所以與RS鎖(通過SELECT … FOR UPDATE語句獲得)對(duì)應(yīng)的行級(jí)鎖也是X鎖(但是該行數(shù)據(jù)實(shí)際上還沒有被修改),這與理論上的IS鎖是有區(qū)別的。 下表為Oracle數(shù)據(jù)庫TM鎖的相容矩陣(Y=Yes,表示相容的請(qǐng)求; N=No,表示不相容的請(qǐng)求;-表示沒有加鎖請(qǐng)求):

T2

T1 S X RS RX SRX -

----------------------------------------------------

S Y N Y N N Y

X N N N N N Y

RS Y N Y Y Y Y

RX N N Y Y N Y

SRX N N Y N N Y

- Y Y Y Y Y Y

表一:Oracle數(shù)據(jù)庫TM鎖的相容矩陣 一方面,當(dāng)Oracle執(zhí)行SELECT…FOR UPDATE、INSERT、UPDATE、DELETE等DML語句時(shí),系統(tǒng)自動(dòng)在所要操作的表上申請(qǐng)表級(jí)RS鎖(SELECT…FOR UPDATE)或RX鎖(INSERT、UPDATE、DELETE),當(dāng)表級(jí)鎖獲得后,系統(tǒng)再自動(dòng)申請(qǐng)TX鎖,并將實(shí)際鎖定的數(shù)據(jù)行的鎖標(biāo)志位置位(指向該TX鎖);另一方面,程序或操作人員也可以通過LOCK TABLE語句來指定獲得某種類型的TM鎖。下表總結(jié)了Oracle中各SQL語句產(chǎn)生TM鎖的情況: SQL語句 表鎖模式 允許的鎖模式

-------------------------------------------------------------------------------------------------

Select * from table_name…… 無 RS、RX、S、SRX、X

Insert into table_name…… RX RS、RX

Update table_name…… RX RS、RX

Delete from table_name…… RX RS、RX

Select * from table_name for update RS RS、RX、S、SRX

lock table table_name in row share mode RS RS、RX、S、SRX

lock table table_name in row exclusive mode RX RS、RX

lock table table_name in share mode S RS、S

lock table table_name in share row exclusive mode SRX RS

lock table table_name in exclusive mode X 無

Oracle創(chuàng)建悲觀鎖和樂觀鎖

為了得到最大的性能,一般數(shù)據(jù)庫都有并發(fā)機(jī)制,不過帶來的問題就是數(shù)據(jù)訪問的沖突。為了解決這個(gè)問題,大多數(shù)數(shù)據(jù)庫用的方法就是數(shù)據(jù)的鎖定。

數(shù)據(jù)的鎖定分為兩種方法,第一種叫做悲觀鎖,第二種叫做樂觀鎖。什么叫悲觀鎖呢,悲觀鎖顧名思義,就是對(duì)數(shù)據(jù)的沖突采取一種悲觀的態(tài)度,也就是說假設(shè)數(shù)據(jù)肯定會(huì)沖突,所以在數(shù)據(jù)開始讀取的時(shí)候就把數(shù)據(jù)鎖定住。而樂觀鎖就是認(rèn)為數(shù)據(jù)一般情況下不會(huì)造成沖突,所以在數(shù)據(jù)進(jìn)行提交更新的時(shí)候,才會(huì)正式對(duì)數(shù)據(jù)的沖突與否進(jìn)行檢測,如果發(fā)現(xiàn)沖突了,則讓用戶返回錯(cuò)誤的信息,讓用戶決定如何去做。

先從悲觀鎖開始說。在SqlServer等其余很多數(shù)據(jù)庫中,數(shù)據(jù)的鎖定通常采用頁級(jí)鎖的方式,也就是說對(duì)一張表內(nèi)的數(shù)據(jù)是一種串行化的更新插入機(jī)制,在任何時(shí)間同一張表只會(huì)插1條數(shù)據(jù),別的想插入的數(shù)據(jù)要等到這一條數(shù)據(jù)插完以后才能依次插入。帶來的后果就是性能的降低,在多用戶并發(fā)訪問的時(shí)候,當(dāng)對(duì)一張表進(jìn)行頻繁操作時(shí),會(huì)發(fā)現(xiàn)響應(yīng)效率很低,數(shù)據(jù)庫經(jīng)常處于一種假死狀態(tài)。而Oracle用的是行級(jí)鎖,只是對(duì)想鎖定的數(shù)據(jù)才進(jìn)行鎖定,其余的數(shù)據(jù)不相干,所以在對(duì)Oracle表中并發(fā)插數(shù)據(jù)的時(shí)候,基本上不會(huì)有任何影響。

注:對(duì)于悲觀鎖是針對(duì)并發(fā)的可能性比較大,而一般在我們的應(yīng)用中用樂觀鎖足以。

Oracle的悲觀鎖需要利用一條現(xiàn)有的連接,分成兩種方式,從SQL語句的區(qū)別來看,就是一種是for update,一種是for update nowait的形式。比如我們看一個(gè)例子。首先建立測試用的數(shù)據(jù)庫表。

CREATE TABLE TEST(ID,NAME,LOCATION,VALUE,CONSTRAINT test_pk PRIMARY KEY(ID))AS SELECT deptno, dname, loc, 1 FROM scott.dept

這里我們利用了Oracle的Sample的scott用戶的表,把數(shù)據(jù)copy到我們的test表中。首先我們看一下for update鎖定方式。首先我們執(zhí)行如下的select for update語句。

select * from test where id = 10 for update

通過這條檢索語句鎖定以后,再開另外一個(gè)sql*plus窗口進(jìn)行操作,再把上面這條sql語句執(zhí)行一便,你會(huì)發(fā)現(xiàn)sqlplus好像死在那里了,好像檢索不到數(shù)據(jù)的樣子,但是也不返回任何結(jié)果,就屬于卡在那里的感覺。這個(gè)時(shí)候是什么原因呢,就是一開始的第一個(gè)Session中的select for update語句把數(shù)據(jù)鎖定住了。由于這里鎖定的機(jī)制是wait的狀態(tài)(只要不表示nowait那就是wait),所以第二個(gè)Session(也就是卡住的那個(gè)sql*plus)中當(dāng)前這個(gè)檢索就處于等待狀態(tài)。當(dāng)?shù)谝粋€(gè)session最后commit或者rollback之后,第二個(gè)session中的檢索結(jié)果就是自動(dòng)跳出來,并且也把數(shù)據(jù)鎖定住。不過如果你第二個(gè)session中你的檢索語句如下所示。

select * from test where id = 10

也就是沒有for update這種鎖定數(shù)據(jù)的語句的話,就不會(huì)造成阻塞了。另外一種情況,就是當(dāng)數(shù)據(jù)庫數(shù)據(jù)被鎖定的時(shí)候,也就是執(zhí)行剛才for update那條sql以后,我們?cè)诹硗庖粋€(gè)session中執(zhí)行for update nowait后又是什么樣呢。比如如下的sql語句。 由于這條語句中是制定采用nowait方式來進(jìn)行檢索,所以當(dāng)發(fā)現(xiàn)數(shù)據(jù)被別的session鎖定中的時(shí)候,就會(huì)迅速返回ORA-00054錯(cuò)誤,內(nèi)容是資源正忙, 但指定以 NOWAIT 方式獲取資源。所以在程序中我們可以采用nowait方式迅速判斷當(dāng)前數(shù)據(jù)是否被鎖定中,如果鎖定中的話,就要采取相應(yīng)的業(yè)務(wù)措施進(jìn)行處理。

select * from test where id = 10 for update nowait

那這里另外一個(gè)問題,就是當(dāng)我們鎖定住數(shù)據(jù)的時(shí)候,我們對(duì)數(shù)據(jù)進(jìn)行更新和刪除的話會(huì)是什么樣呢。比如同樣,我們讓第一個(gè)Session鎖定住id=10的那條數(shù)據(jù),我們?cè)诘诙€(gè)session中執(zhí)行如下語句。

update test set value=2 where id = 10

這個(gè)時(shí)候我們發(fā)現(xiàn)update語句就好像select for update語句一樣也停住卡在這里,當(dāng)你第一個(gè)session放開鎖定以后update才能正常運(yùn)行。當(dāng)你update運(yùn)行后,數(shù)據(jù)又被你update語句鎖定住了,這個(gè)時(shí)候只要你update后還沒有commit,別的session照樣不能對(duì)數(shù)據(jù)進(jìn)行鎖定更新等等。

總之,Oracle中的悲觀鎖就是利用Oracle的Connection對(duì)數(shù)據(jù)進(jìn)行鎖定。在Oracle中,用這種行級(jí)鎖帶來的性能損失是很小的,只是要注意程序邏輯,不要給你一不小心搞成死鎖了就好。而且由于數(shù)據(jù)的及時(shí)鎖定,在數(shù)據(jù)提交時(shí)候就不呼出現(xiàn)沖突,可以省去很多惱人的數(shù)據(jù)沖突處理。缺點(diǎn)就是你必須要始終有一條數(shù)據(jù)庫連接,就是說在整個(gè)鎖定到最后放開鎖的過程中,你的數(shù)據(jù)庫聯(lián)接要始終保持住。與悲觀鎖相對(duì)的,我們有了樂觀鎖。樂觀鎖一開始也說了,就是一開始假設(shè)不會(huì)造成數(shù)據(jù)沖突,在最后提交的時(shí)候再進(jìn)行數(shù)據(jù)沖突檢測。在樂觀鎖中,我們有3種

常用的做法來實(shí)現(xiàn)。

[1]第一種就是在數(shù)據(jù)取得的時(shí)候把整個(gè)數(shù)據(jù)都copy到應(yīng)用中,在進(jìn)行提交的時(shí)候比對(duì)當(dāng)前數(shù)據(jù)庫中的數(shù)據(jù)和開始的時(shí)候更新前取得的數(shù)據(jù)。當(dāng)發(fā)現(xiàn)兩個(gè)數(shù)據(jù)一模一樣以后,就表示沒有沖突可以提交,否則則是并發(fā)沖突,需要去用業(yè)務(wù)邏輯進(jìn)行解決。

[2]第二種樂觀鎖的做法就是采用版本戳,這個(gè)在Hibernate中得到了使用。采用版本戳的話,首先需要在你有樂觀鎖的數(shù)據(jù)庫table上建立一個(gè)新的column,比如為number型,當(dāng)你數(shù)據(jù)每更新一次的時(shí)候,版本數(shù)就會(huì)往上增加1。比如同樣有2個(gè)session同樣對(duì)某條數(shù)據(jù)進(jìn)行操作。兩者都取到當(dāng)前的數(shù)據(jù)的版本號(hào)為1,當(dāng)?shù)谝粋€(gè)session進(jìn)行數(shù)據(jù)更新后,在提交的時(shí)候查看到當(dāng)前數(shù)據(jù)的版本還為1,和自己一開始取到的版本相同。就正式提交,然后把版本號(hào)增加1,這個(gè)時(shí)候當(dāng)前數(shù)據(jù)的版本為2。當(dāng)?shù)诙€(gè)session也更新了數(shù)據(jù)提交的時(shí)候,發(fā)現(xiàn)數(shù)據(jù)庫中版本為2,和一開始這個(gè)session取到的版本號(hào)不一致,就知道別人更新過此條數(shù)據(jù),這個(gè)

時(shí)候再進(jìn)行業(yè)務(wù)處理,比如整個(gè)Transaction都Rollback等等操作。在用版本戳的時(shí)候,可以在應(yīng)用程序側(cè)使用版本戳的驗(yàn)證,也可以在數(shù)據(jù)庫側(cè)采用Trigger(觸發(fā)器)來進(jìn)行驗(yàn)證。不過數(shù)據(jù)庫的Trigger的性能開銷還是比較的大,所以能在應(yīng)用側(cè)進(jìn)行驗(yàn)證的話還是推薦不用Trigger。

[3]第三種做法和第二種做法有點(diǎn)類似,就是也新增一個(gè)Table的Column,不過這次這個(gè)column是采用timestamp型,存儲(chǔ)數(shù)據(jù)最后更新的時(shí)間。在Oracle9i以后可以采用新的數(shù)據(jù)類型,也就是timestamp with time zone類型來做時(shí)間戳。這種Timestamp的數(shù)據(jù)精度在Oracle的時(shí)間類型中是最高的,精確到微秒(還沒與到納秒的級(jí)別),一般來說,加上數(shù)據(jù)庫處理時(shí)間和人的思考動(dòng)作時(shí)間,微秒級(jí)別是非常非常夠了,其實(shí)只要精確到毫秒甚至秒都應(yīng)該沒有什么問題。和剛才的版本戳類似,也是在更新提交的時(shí)候檢查當(dāng)前數(shù)據(jù)庫中數(shù)據(jù)的時(shí)間戳和自己更新前取到的時(shí)間戳進(jìn)行對(duì)比,如果一致則OK,否則就是版本沖突。如果不想把代碼寫在程序中或者由于別的原因無法把代碼寫在現(xiàn)有的程序中,也可以把這個(gè)時(shí)間戳樂觀鎖邏輯寫在Trigger或者存儲(chǔ)過程中。

不知道這個(gè)是不是你需要的...

oracle數(shù)據(jù)庫訪問中要控制加鎖怎樣實(shí)現(xiàn)

鎖是 數(shù)據(jù)庫保護(hù)數(shù)據(jù)表的一種機(jī)制,通常是自動(dòng)的,分級(jí)別的,如果你訪問一個(gè)表的并發(fā)量太大,可以試試拆分這個(gè)表,比如按日期拆分成月表,或者利用oracle的功能(分區(qū))進(jìn)行拆分來分散壓力,如果沒有依據(jù)拆分的話,可以做成實(shí)體化快照,將一些查詢類的操作指向這個(gè)快照,分?jǐn)偙淼脑L問量,也可以通過提升硬件,比如上SSD磁盤,然后將這個(gè)表放到這個(gè)磁盤上,提高訪問速度。

怎樣在oracle 給表加鎖??

lock table 表名 exclusive mode nowait; -- 鎖整個(gè)表

select * from 表名 where XXX for update nowaitl -- 鎖符合條件的記錄


當(dāng)前標(biāo)題:oracle鎖怎么建,oracle加鎖
本文鏈接:http://weahome.cn/article/dssiiei.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部