久久久精品一区ed2k-女人被男人叉到高潮的视频-中文字幕乱码一区久久麻豆樱花-俄罗斯熟妇真实视频

oracle如何寫悲觀鎖,oracle悲觀鎖和樂(lè)觀

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

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

成都創(chuàng)新互聯(lián)從2013年開始,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目做網(wǎng)站、成都做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元洛隆做網(wǎng)站,已為上家服務(wù),為洛隆各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18980820575

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

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

[2]第二種樂(lè)觀鎖的做法就是采用版本戳,這個(gè)在Hibernate中得到了使用。采用版本戳的話,首先需要在你有樂(lè)觀鎖的數(shù)據(jù)庫(kù)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ù)庫(kù)中版本為2,和一開始這個(gè)session取到的版本號(hào)不一致,就知道別人更新過(guò)此條數(shù)據(jù),這個(gè)

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

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

平時(shí)使用oracle時(shí),為什么會(huì)鎖表

數(shù)據(jù)庫(kù)事務(wù)及隔離級(jí)別

隔離級(jí)別:臟讀、幻讀、一致讀、不可重復(fù)讀、更新丟失

1.臟讀(Dirty Reads):一個(gè)事務(wù)開始讀取了某行數(shù)據(jù)但是另外一個(gè)事務(wù)已經(jīng)更新了此數(shù)據(jù)但沒(méi)有能夠及時(shí)提交。這是相當(dāng)危險(xiǎn)很可能所有操作都被回滾

2.幻讀(Phantom Reads):也稱為幻像(幻影)。事務(wù)在操作過(guò)程中進(jìn)行兩次查詢,第二次查詢結(jié)果包含了第一次查詢中未出現(xiàn)的數(shù)據(jù)(這里并不要求兩次查詢SQL語(yǔ)句相同)這是因?yàn)樵趦纱尾樵冞^(guò)程中有另外一個(gè)事務(wù)插入數(shù)據(jù)造成的

3.不可重復(fù)讀(Non-repeatable Reads):一個(gè)事務(wù)對(duì)同一行數(shù)據(jù)重復(fù)讀取兩次但是卻得到了不同結(jié)果。例如在兩次讀取中途有另外一個(gè)事務(wù)對(duì)該行數(shù)據(jù)進(jìn)行了修改并提交

4.兩次更新問(wèn)題(Second lost updates problem):無(wú)法重復(fù)讀取特例,有兩個(gè)并發(fā)事務(wù)同時(shí)讀取同一行數(shù)據(jù)然后其中一個(gè)對(duì)它進(jìn)行修改提交而另一個(gè)也進(jìn)行了修改提交這就會(huì)造成第一次寫操作失效

5.更新丟失(Lost update):兩個(gè)事務(wù)都同時(shí)更新一行數(shù)據(jù)但是第二個(gè)事務(wù)卻中途失敗退出導(dǎo)致對(duì)數(shù)據(jù)兩個(gè)修改都失效了這是系統(tǒng)沒(méi)有執(zhí)行任何鎖操作因此并發(fā)事務(wù)并沒(méi)有被隔離開

20、鎖是什么?

鎖:在所有的DBMS(數(shù)據(jù)庫(kù)管理系統(tǒng))中,鎖是實(shí)現(xiàn)事務(wù)的關(guān)鍵,鎖可以保證事務(wù)的完整性和并發(fā)性。與現(xiàn)實(shí)生活中鎖一樣,它可以使某些數(shù)據(jù)的擁有者,在某段時(shí)間內(nèi)不能使用某些數(shù)據(jù)或數(shù)據(jù)結(jié)構(gòu)。當(dāng)然鎖還分級(jí)別的。

鎖分為行級(jí)鎖和表鎖。

行級(jí)鎖:主要是在執(zhí)行操作過(guò)程中,鎖定指定的行。

主要的鎖行語(yǔ)句有:insert ,update,delete ,及select ....for update。

表鎖:指在運(yùn)行操作指令過(guò)程中,由用戶指定鎖定某張表。lock table XXX in mode share;

共享鎖,排他鎖,共享排它,行共享,行排他。

鎖模式包括?

共享鎖:(讀取)操作創(chuàng)建的鎖。其他用戶可以并發(fā)讀取數(shù)據(jù),但任何事物都不能獲取數(shù)據(jù)上的排它鎖,直到已釋放所有共享鎖。

排他鎖(X鎖):對(duì)數(shù)據(jù)A加上排他鎖后,則其他事務(wù)不能再對(duì)A加任任何類型的封鎖。獲準(zhǔn)排他鎖的事務(wù)既能讀數(shù)據(jù),又能修改數(shù)據(jù)。

更新鎖:更新 (U) 鎖可以防止通常形式的死鎖。如果兩個(gè)事務(wù)獲得了資源上的共享模式鎖,然后試圖同時(shí)更新數(shù)據(jù),則兩個(gè)事務(wù)需都要轉(zhuǎn)換共享鎖為排它 (X) 鎖,并且每個(gè)事務(wù)都等待另一個(gè)事務(wù)釋放共享模式鎖,因此發(fā)生死鎖。

若要避免這種潛 在的死鎖問(wèn)題,請(qǐng)使用更新 (U) 鎖。一次只有一個(gè)事務(wù)可以獲得資源的更新 (U) 鎖。如果事務(wù)修改資源,則更新 (U) 鎖轉(zhuǎn)換為排它 (X) 鎖。否則,鎖轉(zhuǎn)換為共享鎖。

鎖的粒度主要有以下幾種類型:

行鎖: 粒度最小,并發(fā)性最高

頁(yè)鎖:一次鎖定一頁(yè)。25個(gè)行鎖可升級(jí)為一個(gè)頁(yè)鎖。

表鎖:粒度大,并發(fā)性低

數(shù)據(jù)庫(kù)鎖:控制整個(gè)數(shù)據(jù)庫(kù)操作

樂(lè)觀鎖:樂(lè)觀鎖假設(shè)認(rèn)為數(shù)據(jù)一般情況下不會(huì)造成沖突,所以在數(shù)據(jù)進(jìn)行提交更新的時(shí)候,才會(huì)正式對(duì)數(shù)據(jù)的沖突與否進(jìn)行檢測(cè),如果發(fā)現(xiàn)沖突了,則讓返回用戶錯(cuò)誤的信息,讓用戶決定如何去做。一般的實(shí)現(xiàn)樂(lè)觀鎖的方式就是記錄數(shù)據(jù)版本。

悲觀鎖:每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人會(huì)修改,所以每次在拿數(shù)據(jù)的時(shí)候都會(huì)上鎖,這樣別人想拿這個(gè)數(shù)據(jù)就會(huì)block直到它拿到鎖。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)里邊就用到了很多這種鎖機(jī)制,比如行鎖,表鎖,讀鎖,寫鎖等,都是在做操作之前先上鎖。

20、數(shù)據(jù)庫(kù)的樂(lè)觀鎖和悲觀鎖是什么? oracle 是行級(jí)鎖

數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)中,并發(fā)控制的任務(wù)是:確保在多個(gè)事務(wù)同時(shí)存取同一數(shù)據(jù)時(shí),不破壞事務(wù)的隔離性和統(tǒng)一性以及數(shù)據(jù)庫(kù)的統(tǒng)一性。

悲觀鎖:假定會(huì)發(fā)生并發(fā)沖突,屏蔽一切可能違反數(shù)據(jù)完整性的操作

樂(lè)觀鎖:假設(shè)不會(huì)發(fā)生并發(fā)沖突,只在提交操作時(shí)檢查是否違反數(shù)據(jù)完整性。

21、悲觀鎖和樂(lè)觀鎖的區(qū)別,怎么實(shí)現(xiàn)

悲觀鎖:一段執(zhí)行邏輯加上悲觀鎖,不同線程同時(shí)執(zhí)行時(shí),只能有一個(gè)線程執(zhí)行,其他的線程在入口處等待,直到鎖被釋放。

樂(lè)觀鎖:一段執(zhí)行邏輯加上樂(lè)觀鎖,不同線程同時(shí)執(zhí)行時(shí),可以同時(shí)進(jìn)入執(zhí)行,在最后更新數(shù)據(jù)的時(shí)候要檢查這些數(shù)據(jù)是否被其他線程修改了(版本和執(zhí)行初是否相同),沒(méi)有修改則進(jìn)行更新,否則放棄本次操作。

Oracle數(shù)據(jù)庫(kù)鎖的常用類型有哪些

Oracle數(shù)據(jù)庫(kù)的鎖類型

根據(jù)保護(hù)的對(duì)象不同,Oracle數(shù)據(jù)庫(kù)鎖可以分為以下幾大類:DML鎖(data locks,數(shù)據(jù)鎖),用于保護(hù)數(shù)據(jù)的完整性;DDL鎖(dictionary locks,字典鎖),用于保護(hù)數(shù)據(jù)庫(kù)對(duì)象的結(jié)構(gòu),如表、索引等的結(jié)構(gòu)定義;內(nèi)部鎖和閂(internal locks and latches),保護(hù)數(shù)據(jù)庫(kù)的內(nèi)部結(jié)構(gòu)。

DML鎖的目的在于保證并發(fā)情況下的數(shù)據(jù)完整性,本文主要討論DML鎖。在Oracle數(shù)據(jù)庫(kù)中,DML鎖主要包括TM鎖和TX鎖,其中TM鎖稱為表級(jí)鎖,TX鎖稱為事務(wù)鎖或行級(jí)鎖。

當(dāng)Oracle執(zhí)行DML語(yǔ)句時(shí),系統(tǒng)自動(dòng)在所要操作的表上申請(qǐng)TM類型的鎖。當(dāng)TM鎖獲得后,系統(tǒng)再自動(dòng)申請(qǐng)TX類型的鎖,并將實(shí)際鎖定的數(shù)據(jù)行的鎖標(biāo)志位進(jìn)行置位。這樣在事務(wù)加鎖前檢查TX鎖相容性時(shí)就不用再逐行檢查鎖標(biāo)志,而只需檢查TM鎖模式的相容性即可,大大提高了系統(tǒng)的效率。TM鎖包括了SS、SX、S、X等多種模式,在數(shù)據(jù)庫(kù)中用0-6來(lái)表示。不同的SQL操作產(chǎn)生不同類型的TM鎖。如表1所示。

在數(shù)據(jù)行上只有X鎖(排他鎖)。在 Oracle數(shù)據(jù)庫(kù)中,當(dāng)一個(gè)事務(wù)首次發(fā)起一個(gè)DML語(yǔ)句時(shí)就獲得一個(gè)TX鎖,該鎖保持到事務(wù)被提交或回滾。當(dāng)兩個(gè)或多個(gè)會(huì)話在表的同一條記錄上執(zhí)行DML語(yǔ)句時(shí),第一個(gè)會(huì)話在該條記錄上加鎖,其他的會(huì)話處于等待狀態(tài)。當(dāng)?shù)谝粋€(gè)會(huì)話提交后,TX鎖被釋放,其他會(huì)話才可以加鎖。

當(dāng)Oracle數(shù)據(jù)庫(kù)發(fā)生TX鎖等待時(shí),如果不及時(shí)處理常常會(huì)引起Oracle數(shù)據(jù)庫(kù)掛起,或?qū)е滤梨i的發(fā)生,產(chǎn)生ORA-60的錯(cuò)誤。這些現(xiàn)象都會(huì)對(duì)實(shí)際應(yīng)用產(chǎn)生極大的危害,如長(zhǎng)時(shí)間未響應(yīng),大量事務(wù)失敗等。

TX鎖等待的分析

在介紹了有關(guān)地Oracle數(shù)據(jù)庫(kù)鎖的種類后,下面討論如何有效地監(jiān)控和解決鎖等待現(xiàn)象,及在產(chǎn)生死鎖時(shí)如何定位死鎖的原因。

監(jiān)控鎖的相關(guān)視圖 數(shù)據(jù)字典是Oracle數(shù)據(jù)庫(kù)的重要組成部分,用戶可以通過(guò)查詢數(shù)據(jù)字典視圖來(lái)獲得數(shù)據(jù)庫(kù)的信息。和鎖相關(guān)的數(shù)據(jù)字典視圖如表2所示。

TX鎖等待的監(jiān)控和解決在日常工作中,如果發(fā)現(xiàn)在執(zhí)行某條SQL時(shí)數(shù)據(jù)庫(kù)長(zhǎng)時(shí)間沒(méi)有響應(yīng),很可能是產(chǎn)生了TX鎖等待的現(xiàn)象。為解決這個(gè)問(wèn)題,首先應(yīng)該找出持鎖的事務(wù),然后再進(jìn)行相關(guān)的處理,如提交事務(wù)或強(qiáng)行中斷事務(wù)。

死鎖的監(jiān)控和解決在數(shù)據(jù)庫(kù)中,當(dāng)兩個(gè)或多個(gè)會(huì)話請(qǐng)求同一個(gè)資源時(shí)會(huì)產(chǎn)生死鎖的現(xiàn)象。死鎖的常見(jiàn)類型是行級(jí)鎖死鎖和頁(yè)級(jí)鎖死鎖,Oracle數(shù)據(jù)庫(kù)中一般使用行級(jí)鎖。下面主要討論行級(jí)鎖的死鎖現(xiàn)象。

當(dāng)Oracle檢測(cè)到死鎖產(chǎn)生時(shí),中斷并回滾死鎖相關(guān)語(yǔ)句的執(zhí)行,報(bào)ORA-00060的錯(cuò)誤并記錄在數(shù)據(jù)庫(kù)的日志文件alertSID.log中。同時(shí)在user_dump_dest下產(chǎn)生了一個(gè)跟蹤文件,詳細(xì)描述死鎖的相關(guān)信息。

在日常工作中,如果發(fā)現(xiàn)在日志文件中記錄了ora-00060的錯(cuò)誤信息,則表明產(chǎn)生了死鎖。這時(shí)需要找到對(duì)應(yīng)的跟蹤文件,根據(jù)跟蹤文件的信息定位產(chǎn)生的原因。

如果查詢結(jié)果表明,死鎖是由于bitmap索引引起的,將IND_T_PRODUCT_HIS_STATE索引改為normal索引后,即可解決死鎖的問(wèn)題。

表1 Oracle的TM鎖類型

鎖模式 鎖描述 解釋 SQL操作

0 none

1 NULL 空 Select

2 SS(Row-S) 行級(jí)共享鎖,其他對(duì)象只能查詢這些數(shù)據(jù)行 Select for update、Lock for update、Lock row share

3 SX(Row-X) 行級(jí)排它鎖,在提交前不允許做DML操作 Insert、Update、Delete、Lock row share

4 S(Share) 共享鎖 Create index、Lock share

5 SSX(S/Row-X) 共享行級(jí)排它鎖 Lock share row exclusive

6 X(Exclusive) 排它鎖 Alter table、Drop able、Drop index、Truncate table 、Lock exclusive

表2 數(shù)據(jù)字典視圖說(shuō)明

視圖名 描述 主要字段說(shuō)明

v$session 查詢會(huì)話的信息和鎖的信息。 sid,serial#:表示會(huì)話信息。

program:表示會(huì)話的應(yīng)用程序信息。

row_wait_obj#:表示等待的對(duì)象。

和dba_objects中的object_id相對(duì)應(yīng)。

v$session_wait 查詢等待的會(huì)話信息。 sid:表示持有鎖的會(huì)話信息。

Seconds_in_wait:表示等待持續(xù)的時(shí)間信息

Event:表示會(huì)話等待的事件。

v$lock 列出系統(tǒng)中的所有的鎖。 Sid:表示持有鎖的會(huì)話信息。

Type:表示鎖的類型。值包括TM和TX等。

ID1:表示鎖的對(duì)象標(biāo)識(shí)。

lmode,request:表示會(huì)話等待的鎖模式的信

息。用數(shù)字0-6表示,和表1相對(duì)應(yīng)。

dba_locks 對(duì)v$lock的格式化視圖。 Session_id:和v$lock中的Sid對(duì)應(yīng)。

Lock_type:和v$lock中的type對(duì)應(yīng)。

Lock_ID1: 和v$lock中的ID1對(duì)應(yīng)。

Mode_held,mode_requested:和v$lock中

的lmode,request相對(duì)應(yīng)。

v$locked_object 只包含DML的鎖信息,包括回滾段和會(huì)話信息。 Xidusn,xidslot,xidsqn:表示回滾段信息。和

v$transaction相關(guān)聯(lián)。

Object_id:表示被鎖對(duì)象標(biāo)識(shí)。

Session_id:表示持有鎖的會(huì)話信息。

Locked_mode:表示會(huì)話等待的鎖模式的信

息,和v$lock中的lmode一致。

col owner for a12

col object_name for a16

select b.owner,b.object_name,l.session_id,l.locked_mode

from v$locked_object l, dba_objects b

where b.object_id=l.object_id;

select t2.username,t2.sid,t2.serial#,t2.logon_time

from v$locked_object t1,v$session t2

where t1.session_id=t2.sid order by t2.logon_time;

如果有長(zhǎng)期出現(xiàn)的一列,可能是沒(méi)有釋放的鎖。我們可以用下面SQL語(yǔ)句殺掉長(zhǎng)期沒(méi)有釋放非正常的鎖:

alter system kill session 'sid,serial# ';

如果出現(xiàn)了鎖的問(wèn)題, 某個(gè)DML操作可能等待很久沒(méi)有反應(yīng)。

當(dāng)你采用的是直接連接數(shù)據(jù)庫(kù)的方式,也不要用OS系統(tǒng)命令 $kill process_num 或者 $kill -9 process_num來(lái)終止用戶連接,因?yàn)橐粋€(gè)用戶進(jìn)程可能產(chǎn)生一個(gè)以上的鎖, 殺OS進(jìn)程并不能徹底清除鎖的問(wèn)題

Oracle鎖表(死鎖) 2011-05-03 17:46:41| 分類: Java技術(shù) | 標(biāo)簽: |字號(hào)大中小 訂閱 .

數(shù)據(jù)庫(kù)與操作系統(tǒng)一樣,是一個(gè)多用戶使用的共享資源。 當(dāng)多個(gè)用戶并發(fā)地存取數(shù)據(jù)時(shí),在數(shù)據(jù)庫(kù)中就會(huì)發(fā)生多個(gè)事務(wù)同時(shí)存取同一數(shù)據(jù)地情況。 若對(duì)并發(fā)操作不加控制就可能會(huì)讀取和存儲(chǔ)不正確地?cái)?shù)據(jù),破壞數(shù)據(jù)庫(kù)地一致性。 加鎖時(shí)實(shí)現(xiàn)數(shù)據(jù)庫(kù)并發(fā)控制地一個(gè)非常重要地技術(shù)。 在實(shí)際應(yīng)用中經(jīng)常會(huì)遇到地與鎖相關(guān)地異常情況,當(dāng)兩個(gè)事務(wù)需要一組有沖突的鎖,而不能將事務(wù)繼續(xù)下去的話,就會(huì)出現(xiàn)死鎖,嚴(yán)重影響應(yīng)用的正常執(zhí)行。

在數(shù)據(jù)庫(kù)中有兩種基本的鎖類型:排它鎖(Exclusive Locks,即X鎖)和共享鎖(即S鎖)。當(dāng)數(shù)據(jù)對(duì)象被加上排它鎖時(shí),其他的事務(wù)不能不能對(duì)它讀取和修改。加了共享鎖的數(shù)據(jù)對(duì)象可以被其他事務(wù)讀取,但不能修改。數(shù)據(jù)庫(kù)利用這兩種基本的鎖類型來(lái)對(duì)數(shù)據(jù)庫(kù)的事務(wù)進(jìn)行并發(fā)控制。

死鎖的第一種情況:

一個(gè)用戶A訪問(wèn)表A(鎖住了表A),然后又訪問(wèn)表B; 另一個(gè)用戶B訪問(wèn)表B(鎖住了表B),然后企圖訪問(wèn)表A;這時(shí)用戶A由于用戶B已經(jīng)鎖住表B,它必須等待用戶B釋放表B才能繼續(xù),同樣用戶B要等用戶A釋放表A才能繼續(xù),這就死鎖產(chǎn)生了。

解決方法:

這種死鎖比較常見(jiàn),是由于程序的BUG產(chǎn)生的,除了調(diào)整程序的邏輯沒(méi)有其它的辦法。仔細(xì)分析程序的邏輯,對(duì)于數(shù)據(jù)庫(kù)的多表操作時(shí),盡量按照同樣的順序進(jìn)行處理,盡量避免同時(shí)鎖定兩個(gè)資源,如操作A和B兩張表時(shí),總是按先A后B的順序處理,必須同時(shí)鎖定兩個(gè)資源時(shí),要保證在任何時(shí)刻都應(yīng)該按照相同的順序來(lái)鎖定資源。

死鎖的第二種情況

用戶A查詢一條記錄,然后修改該條記錄;這時(shí)用戶B修改該條記錄,這時(shí)用戶A的事務(wù)里鎖的性質(zhì)由查詢的共享鎖企圖上升到獨(dú)占鎖,而用戶B里的獨(dú)占鎖由于A有共享鎖存在必須等A釋放掉共享鎖,而A由于B的獨(dú)占鎖而無(wú)法上升到獨(dú)占鎖也就不可能釋放共享鎖,于是出現(xiàn)了死鎖。這種死鎖比較隱蔽,但在稍大點(diǎn)的項(xiàng)目種經(jīng)常發(fā)生,如在某項(xiàng)目中,頁(yè)面上的按鈕點(diǎn)擊后,沒(méi)有使按鈕立刻失效,使得用戶會(huì)多次快速點(diǎn)擊同一按鈕,這樣同一段代碼對(duì)數(shù)據(jù)庫(kù)同一條記錄進(jìn)行多次操作,很容易就出現(xiàn)這種死鎖的情況。

解決方法:

1、對(duì)于按鈕等控件,點(diǎn)擊后使其立刻失效,不讓用戶重復(fù)點(diǎn)擊,避免對(duì)同時(shí)對(duì)同一條記錄操作。

2、使用樂(lè)觀鎖進(jìn)行控制。樂(lè)觀鎖大多是基于數(shù)據(jù)版本(version)記錄機(jī)制實(shí)現(xiàn)。即為數(shù)據(jù)增加一個(gè)版本標(biāo)識(shí),在基于數(shù)據(jù)庫(kù)表的版本解決方案中,一般是通過(guò)為數(shù)據(jù)庫(kù)增加一個(gè)“version”字段來(lái)實(shí)現(xiàn)。讀取處數(shù)據(jù)時(shí),將此版本號(hào)一同讀出,之后更新時(shí),對(duì)此版本號(hào)加一。此時(shí),將提交的數(shù)據(jù)的版本數(shù)據(jù)與數(shù)據(jù)庫(kù)表對(duì)應(yīng)記錄的當(dāng)前版本信息進(jìn)行比對(duì),如果提交的數(shù)據(jù)版本號(hào)大于數(shù)據(jù)庫(kù)表當(dāng)前版本號(hào),則予以更新,否則認(rèn)為是過(guò)期數(shù)據(jù)。樂(lè)觀鎖機(jī)制避免了長(zhǎng)事務(wù)中的數(shù)據(jù)庫(kù)加鎖開銷(用戶A和用戶B操作過(guò)程中,都沒(méi)有對(duì)數(shù)據(jù)庫(kù)加鎖),大大提升了大并發(fā)量下的系統(tǒng)整體性表現(xiàn)。 Hibernate在其數(shù)據(jù)訪問(wèn)引擎中內(nèi)置了樂(lè)觀鎖實(shí)現(xiàn)。需要注意的是,由于樂(lè)觀鎖機(jī)制是我們的系統(tǒng)中實(shí)現(xiàn),來(lái)自外部系統(tǒng)的用戶更新操作不受我們系統(tǒng)的控制,因此可能會(huì)造成臟數(shù)據(jù)被更新到數(shù)據(jù)庫(kù)中。

3、使用悲觀鎖進(jìn)行控制。悲觀鎖大多數(shù)情況下依靠數(shù)據(jù)庫(kù)的鎖機(jī)制實(shí)現(xiàn),如Oracle的select.......for update語(yǔ)句,以保證操作最大程度的獨(dú)占性。但隨之而來(lái)的就是數(shù)據(jù)庫(kù)性能的大量開銷,特別是對(duì)長(zhǎng)事務(wù)而言,這樣的開銷往往無(wú)法承受。如一個(gè)金融系統(tǒng),當(dāng)某個(gè)操作員讀取用戶的數(shù)據(jù),并在讀出的用戶數(shù)據(jù)的基礎(chǔ)上進(jìn)行修改時(shí)(如更改用戶帳戶余額),如果采用悲觀鎖機(jī)制,也就意味整個(gè)操作過(guò)程中(從操作員讀出數(shù)據(jù)、開始修改直至提交修改結(jié)果的全過(guò)程,甚至還包括操作員中途去煮咖啡的時(shí)間),數(shù)據(jù)庫(kù)記錄始終處于加鎖狀態(tài),可以想見(jiàn),如果面對(duì)成百上千個(gè)并發(fā),這樣的情況將導(dǎo)致災(zāi)難性的結(jié)果。所以,采用悲觀鎖進(jìn)行控制時(shí)一定要考慮清楚。

死鎖的第三種情況

如果在事務(wù)種執(zhí)行了一條不滿足條件的update語(yǔ)句,則執(zhí)行全表掃描,把行級(jí)鎖上升為表級(jí)鎖,多個(gè)這樣的事務(wù)執(zhí)行之后,就很容易發(fā)生死鎖和阻塞。類似的情況還有當(dāng)表種的數(shù)據(jù)量非常龐大而索引建的過(guò)少或不合適的時(shí)候,使得經(jīng)常發(fā)生全表掃描,最終應(yīng)用系統(tǒng)會(huì)越來(lái)越慢,最終發(fā)生阻塞或死鎖。

解決方法:

SQL語(yǔ)句中不要使用太復(fù)雜的關(guān)聯(lián)多表的查詢;使用“執(zhí)行計(jì)劃”對(duì)SQL語(yǔ)句進(jìn)行 分析,對(duì)于有全表掃描的SQL語(yǔ)句,建立相應(yīng)的索引進(jìn)行優(yōu)化。

***查詢死鎖表以及解鎖表***

通過(guò)select * from v$locked_object

可以獲得被鎖的對(duì)象的object_id及產(chǎn)生鎖的會(huì)話sid,通過(guò)查詢結(jié)果中的object_id,可以查詢到具體被鎖的對(duì)象。

鎖有以下幾種模式:

0:none

1:null 空

2:Row-S 行共享(RS / S鎖):共享表鎖

3:Row-X 行專用(RX / X鎖):用于行的修改

4:Share 共享鎖(S):阻止其他DML操作

5:S/Row-X 共享行專用(SRX):阻止其他事務(wù)操作

6:exclusive 專用(X):獨(dú)立訪問(wèn)使用

數(shù)字越大鎖級(jí)別越高, 影響的操作越多。

一般的查詢語(yǔ)句如select ... from ... ;是小于2的鎖, 有時(shí)會(huì)在v$locked_object出現(xiàn)。

select ... from ... for update; 是2的鎖。

當(dāng)對(duì)話使用for update子串打開一個(gè)游標(biāo)時(shí),

所有返回集中的數(shù)據(jù)行都將處于行級(jí)(Row-X)獨(dú)占式鎖定,

其他對(duì)象只能查詢這些數(shù)據(jù)行,不能進(jìn)行update、delete或select...for update操作。

insert / update / delete ... ; 是3的鎖。

沒(méi)有commit之前插入同樣的一條記錄會(huì)沒(méi)有反應(yīng),

因?yàn)楹笠粋€(gè)3的鎖會(huì)一直等待上一個(gè)3的鎖, 我們必須釋放掉上一個(gè)才能繼續(xù)工作。

創(chuàng)建索引的時(shí)候也會(huì)產(chǎn)生3,4級(jí)別的鎖。

locked_mode為2,3,4不影響DML(insert,delete,update,select)操作,

但DDL(alter,drop等)操作會(huì)提示ora-00054錯(cuò)誤。

有主外鍵約束時(shí) update / delete ... ; 可能會(huì)產(chǎn)生4,5的鎖。

DDL語(yǔ)句時(shí)是6的鎖。

以DBA角色, 查看當(dāng)前數(shù)據(jù)庫(kù)里鎖的情況可以用如下SQL語(yǔ)句:

select object_id,session_id,locked_mode from v$locked_object;

select t2.username,t2.sid,t2.serial#,t2.logon_time

from v$locked_object t1,v$session t2

where t1.session_id=t2.sid order by t2.logon_time;

如果有長(zhǎng)期出現(xiàn)的一列,可能是沒(méi)有釋放的鎖。

我們可以用下面SQL語(yǔ)句殺掉長(zhǎng)期沒(méi)有釋放非正常的鎖:

分享名稱:oracle如何寫悲觀鎖,oracle悲觀鎖和樂(lè)觀
當(dāng)前URL:http://www.sd-ha.com/article18/dscohdp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、網(wǎng)站維護(hù)、企業(yè)網(wǎng)站制作、靜態(tài)網(wǎng)站、網(wǎng)站設(shè)計(jì)品牌網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司