bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

oracle怎么加樂觀鎖 oracle 如何釋放鎖

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

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

專注于為中小企業(yè)提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)安陽免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

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

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

當(dāng)Oracle執(zhí)行DML語句時(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ù)庫中用0-6來表示。不同的SQL操作產(chǎn)生不同類型的TM鎖。如表1所示。

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

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

TX鎖等待的分析

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

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

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

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

當(dāng)Oracle檢測(cè)到死鎖產(chǎn)生時(shí),中斷并回滾死鎖相關(guān)語句的執(zhí)行,報(bào)ORA-00060的錯(cuò)誤并記錄在數(shù)據(jù)庫的日志文件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索引后,即可解決死鎖的問題。

表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ù)字典視圖說明

視圖名 描述 主要字段說明

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;

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

alter system kill session 'sid,serial# ';

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

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

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

數(shù)據(jù)庫與操作系統(tǒng)一樣,是一個(gè)多用戶使用的共享資源。 當(dāng)多個(gè)用戶并發(fā)地存取數(shù)據(jù)時(shí),在數(shù)據(jù)庫中就會(huì)發(fā)生多個(gè)事務(wù)同時(shí)存取同一數(shù)據(jù)地情況。 若對(duì)并發(fā)操作不加控制就可能會(huì)讀取和存儲(chǔ)不正確地?cái)?shù)據(jù),破壞數(shù)據(jù)庫地一致性。 加鎖時(shí)實(shí)現(xiàn)數(shù)據(jù)庫并發(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ù)庫中有兩種基本的鎖類型:排它鎖(Exclusive Locks,即X鎖)和共享鎖(即S鎖)。當(dāng)數(shù)據(jù)對(duì)象被加上排它鎖時(shí),其他的事務(wù)不能不能對(duì)它讀取和修改。加了共享鎖的數(shù)據(jù)對(duì)象可以被其他事務(wù)讀取,但不能修改。數(shù)據(jù)庫利用這兩種基本的鎖類型來對(duì)數(shù)據(jù)庫的事務(wù)進(jìn)行并發(fā)控制。

死鎖的第一種情況:

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

解決方法:

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

死鎖的第二種情況

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

解決方法:

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

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

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

死鎖的第三種情況

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

解決方法:

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

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

通過select * from v$locked_object

可以獲得被鎖的對(duì)象的object_id及產(chǎn)生鎖的會(huì)話sid,通過查詢結(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ú)立訪問使用

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

一般的查詢語句如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的鎖。

沒有commit之前插入同樣的一條記錄會(huì)沒有反應(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語句時(shí)是6的鎖。

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

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;

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

我們可以用下面SQL語句殺掉長期沒有釋放非正常的鎖:

操作oracle數(shù)據(jù)時(shí)報(bào)樂觀鎖異常

戶A打開應(yīng)用的界面,看到數(shù)據(jù)庫的某條記錄

b.用戶B打開應(yīng)用的界面,看到同樣一條記錄

c. 用戶A對(duì)記錄做了修改

d. 對(duì)于web應(yīng)用而言[假設(shè)沒有應(yīng)用comet類似技術(shù)],通常B不知道這個(gè)修改,這時(shí)B也對(duì)同樣這條記錄做修改,那B就有可能覆蓋A做的修改;

這個(gè)問題在數(shù)據(jù)庫中被稱為丟失更新問題

2.我自己對(duì)這個(gè)問題的理解過程是這樣的:

a. 不知道這個(gè)問題

我在做開發(fā)好長時(shí)間之后才意識(shí)到這個(gè)問題,意識(shí)到這個(gè)問題之后,我后來發(fā)現(xiàn)很長一段時(shí)間內(nèi)都沒真正搞明白為什么這是個(gè)問題-_- 而且我發(fā)現(xiàn)現(xiàn)在周圍的很多同事,尤其是新畢業(yè)的學(xué)生,其實(shí)也一直過了很長時(shí)間都沒明白這個(gè)問題,這說明吧不知道這個(gè)丟失更新問題是一個(gè)非常普遍的問題:)

b.用信號(hào)量以及操作之前再次驗(yàn)證的方法解決

最開始的時(shí)候,測(cè)試發(fā)現(xiàn)了這樣一個(gè)問題,要求解決,我把操作系統(tǒng)的教科書搬來,對(duì)照著寫了一個(gè)信號(hào)量semaphore類[那時(shí)候還是jdk 1.4.2,jdk里面沒有concurrent包],花了好長時(shí)間測(cè)試這個(gè)semaphore的實(shí)現(xiàn)是正確的[重復(fù)發(fā)明輪子的血淚史..],

然后用來控制這個(gè)操作,每次操作前獲取信號(hào)量,然后驗(yàn)證,再做真正的數(shù)據(jù)庫操作。。。相當(dāng)于在應(yīng)用層每次都只做一件事。

c. 再次理解

再后來,我看了Tom的這本9i和10g的書,書中提到前面的丟失更新過程,大概有點(diǎn)明白為什么這是個(gè)問題

8a7315603d51c12ef97a82729cdc4677.png

但是其實(shí)我有個(gè)疑問,對(duì)于數(shù)據(jù)庫中的記錄而言,A做的修改本來就有可能被B覆蓋的,為什么這會(huì)是一個(gè)丟失更新問題呢? 正好項(xiàng)目里面又出現(xiàn)了類似的情況,我仔細(xì)觀察了下,終于明白為什么這是個(gè)問題,以及為什么要使用對(duì)應(yīng)的樂觀鎖悲觀鎖方案了。下面對(duì)此做詳細(xì)說明

3. 一個(gè)比較清楚的場(chǎng)景

下面這個(gè)假設(shè)的實(shí)際場(chǎng)景可以比較清楚的幫助我們理解這個(gè)問題:

假設(shè)當(dāng)當(dāng)網(wǎng)上用戶下單買了本書,這時(shí)數(shù)據(jù)庫中有條訂單號(hào)為001的訂單,其中有個(gè)status字段是’有效’,表示該訂單是有效的;

后臺(tái)管理人員查詢到這條001的訂單,并且看到狀態(tài)是有效的

用戶發(fā)現(xiàn)下單的時(shí)候下錯(cuò)了,于是撤銷訂單,假設(shè)運(yùn)行這樣一條SQL: update order_table set status = ‘取消’ where order_id = 001;

后臺(tái)管理人員由于在b這步看到狀態(tài)有效的,這時(shí),雖然用戶在c這步已經(jīng)撤銷了訂單,可是管理人員并未刷新界面,看到的訂單狀態(tài)還是有效的,于是點(diǎn)擊”發(fā)貨”按鈕,將該訂單發(fā)到物流部門,同時(shí)運(yùn)行類似如下SQL,將訂單狀態(tài)改成已發(fā)貨:update order_table set status = ‘已發(fā)貨’ where order_id = 001

如果當(dāng)當(dāng)?shù)南到y(tǒng)這樣實(shí)現(xiàn),顯然不對(duì)了,肯定要挨罵了,明明已經(jīng)取消了訂單,為什么還會(huì)發(fā)貨呢?而且確實(shí)取消訂單的操作發(fā)生在發(fā)貨操作之前啊。 因?yàn)樵谶@樣的實(shí)現(xiàn)下,后臺(tái)管理人員無論怎么做都有可能會(huì)出錯(cuò),因?yàn)樗蜷_系統(tǒng)看到有效的訂單和他點(diǎn)發(fā)貨之間肯定有個(gè)時(shí)間差,在這個(gè)時(shí)間差的時(shí)候總是存在用戶取消訂單的可能。

4. 當(dāng)時(shí)的詳細(xì)解決方法。幾年前當(dāng)測(cè)試人員告訴我系統(tǒng)存在這個(gè)問題的時(shí)候,我的解決方法是這樣的, 首先,先把操作系統(tǒng)的教科書搬來,然后對(duì)照著了一個(gè)semaphore,然后反復(fù)測(cè)試各種情況證明寫的是正確的; 然后,

1. 獲取一個(gè)信號(hào)量,保證每次只能有一個(gè)線程進(jìn)入下面的步驟

2. 檢查數(shù)據(jù)庫,看這條訂單是否狀態(tài)是有效的

a. 如果有效則繼續(xù),進(jìn)入發(fā)貨步驟 b) 如果無效則返回,釋放信號(hào)量,告訴用戶狀態(tài)已經(jīng)發(fā)生改變

3. 發(fā)貨,釋放信號(hào)量

看到這里,也許很多人要罵我蠢了,直接把SQL語句改成下面這樣吧就可以了么? update order_table set status = ‘已發(fā)貨’ where order_id = 001 and status = ‘有效’ 是的,的確是這樣。雖然我當(dāng)時(shí)的項(xiàng)目的情況比和這個(gè)稍微復(fù)雜一點(diǎn),涉及到多張表格,不能直接這么做,但當(dāng)時(shí)的確不知道這個(gè)更新丟失問題,也沒想到合適的類似方式,于是就在應(yīng)用層做了這么一個(gè)每次實(shí)際上只能有一個(gè)用戶在做真正的更新這樣一個(gè)方式來解決,這樣做的結(jié)果是,在應(yīng)用層單獨(dú)做了類似這么一個(gè)鎖的機(jī)制。我記得當(dāng)時(shí)的項(xiàng)目畢業(yè)答辯的時(shí)候,老師問我同步的這個(gè)問題不直接用數(shù)據(jù)庫的鎖的方案來解決?我當(dāng)時(shí)胡亂回答了下,后來想起來,其實(shí)壓根沒理解老師的意思-_- 而且這樣做有一個(gè)問題,假設(shè)在特殊情況下,這條訂單被DBA直接修改了,沒有經(jīng)過應(yīng)用,那么應(yīng)用做這個(gè)操作也會(huì)是錯(cuò)的,因?yàn)樵?.a到3之前的這段時(shí)間,有可能正好是DBA直接修改的時(shí)候。那么3做的操作也是不對(duì)的。 而且,現(xiàn)實(shí)情況是在后來的幾年開發(fā)過程中,我也的確在一些不同的項(xiàng)目代碼中看到,其他很多人也在使用類似的代碼解決測(cè)試人員告訴他們的這些同步問題-_-

5.正確而簡(jiǎn)潔的解決方法

問題清楚了,也說明了我曾經(jīng)使用的解決方案也是一個(gè)簡(jiǎn)潔直接的解決方案,純粹是把簡(jiǎn)單問題復(fù)雜化,下面說說實(shí)際有效的解決方案; 就這個(gè)丟失更新問題,可以通過數(shù)據(jù)庫的鎖來實(shí)現(xiàn),基本兩種思路,一種是悲觀鎖,另外一種是樂觀鎖; 簡(jiǎn)單的說就是一種假定這樣的問題是高概率的,最好一開始就鎖住,免得更新老是失敗;另外一種假定這樣的問題是小概率的,最后一步做更新的時(shí)候再鎖住,免得鎖住時(shí)間太長影響其他人做有關(guān)操作;

6. 樂觀鎖的方法

這里先說web開發(fā)中常用的樂觀鎖的方法:

1.很簡(jiǎn)單,就是使用前面所說的這樣一條SQL,這其實(shí)是所謂使用”前鏡像”的方式來保證需要更新的數(shù)據(jù)是符合要求的,

update order_table set status = ‘已發(fā)貨’ where order_id = 001 and status = ‘有效’ Tom的書上舉的例子是對(duì)所有列做更新,所以他的SQL大致如下 Update table set col1 = newcol1value, col2 = newcol2value…. where col1 = oldcol1value and col2 = oldcol2value…. 這個(gè)我覺得需要根據(jù)應(yīng)用具體分析,如果需要判斷所有的值,那就判斷所有的值,如果只關(guān)心其中一個(gè)或部分值,那只需要取相關(guān)的值就好了,就比如這里的訂單的狀態(tài)

2.使用版本列[比如時(shí)間戳

這個(gè)方法比較簡(jiǎn)單,也最常用,就是在數(shù)據(jù)庫表格中加一列l(wèi)ast_modified_date,就是最后更新的時(shí)間,每次更新的時(shí)候都將這列設(shè)成systimestamp,當(dāng)前系統(tǒng)時(shí)間;

然后每次更新的時(shí)候,就改成這樣 Update table set col = newvalue where id = ** and last_modified_date = old last_modified_date 這樣,就可以檢驗(yàn)出數(shù)據(jù)庫的值是否在上次查看和這次更新的時(shí)候發(fā)生了變化,如果發(fā)生了變化,那么last_modified_date就變化了,以后的更新就會(huì)返回更新了0行,系統(tǒng)就可以通知用戶數(shù)據(jù)發(fā)生了變化,然后選擇刷新數(shù)據(jù)或者其他流程。

至于這個(gè)last_modified_date的維護(hù),可以選擇讓應(yīng)用每次都維護(hù)這個(gè)值,或者是使用存儲(chǔ)過程來包裝更新的操作,或者是使用觸發(fā)器來更新相關(guān)的值。幾種方法各有利弊,比如應(yīng)用維護(hù)需要保證每段相關(guān)代碼都正確的維護(hù)了這個(gè)值;存儲(chǔ)過程有一定的開銷,通常很多開發(fā)對(duì)寫存儲(chǔ)過程可能也不熟練;觸發(fā)器是簡(jiǎn)單的實(shí)現(xiàn),但是也是有開銷的。具體使用哪種方法需要根據(jù)實(shí)際情況具體取舍。

3.使用校驗(yàn)或Hash值

這種方法和前面的方法類似,無非是根據(jù)其他有實(shí)際意義的列來計(jì)算出一個(gè)虛擬的列,我個(gè)人覺得TOM在介紹這個(gè)純粹是介紹了一種”奇技淫巧”,反正我是在實(shí)際過程中不知道哪里會(huì)需要這樣的解決方案,或許也是因?yàn)槲抑赖奶倭税桑?

4.使用Oracle 10g的ORA_ROWSCN

這個(gè)就是利用10g的一個(gè)ora_rowscn特性,可以對(duì)每行做精確追蹤,不過這個(gè)要求在create table的時(shí)候就指定相關(guān)參數(shù),表格如果創(chuàng)建了以后就不能用alter table來修改了,因?yàn)檫@依賴于物理的實(shí)際存儲(chǔ)。 同樣,我覺得這也可以歸為”奇技淫巧”一類; 具體如果有興趣了解詳情的話,可以參考Tom的書

我們一直都在努力堅(jiān)持原創(chuàng).......請(qǐng)不要一聲不吭,就悄悄拿走。

我原創(chuàng),你原創(chuàng),我們的內(nèi)容世界才會(huì)更加精彩!

【所有原創(chuàng)內(nèi)容版權(quán)均屬TechTarget,歡迎大家轉(zhuǎn)發(fā)分享。但未經(jīng)授權(quán),嚴(yán)禁任何媒體(平面媒體、網(wǎng)絡(luò)媒體、自媒體等)以及微信公眾號(hào)復(fù)制、轉(zhuǎn)載、摘編或以其他方式進(jìn)行使用。】

微信公眾號(hào)

TechTarget

官方微博

TechTarget中國

相關(guān)資源:oracle樂觀鎖和悲觀鎖詳細(xì)教程_oracle的樂觀鎖-Oracle文檔類資源...

點(diǎn)擊閱讀全文

打開CSDN,閱讀體驗(yàn)更佳

Oracle數(shù)據(jù)庫悲觀鎖與樂觀鎖_diweikang的博客

注:對(duì)于悲觀鎖是針對(duì)并發(fā)的可能性比較大,而一般在我們的應(yīng)用中用樂觀鎖足以。 Oracle的悲觀鎖需要利用一條現(xiàn)有的連接,分成兩種方式,從SQL語句的區(qū)別來看,就是一種是for update,一種是for update nowait的形式。 1. 執(zhí)行select xxx ...

ORACLE悲觀鎖和樂觀鎖_hongwei3344661的博客

1、無論是選擇悲觀鎖策略,還是樂觀鎖策略。如果一個(gè)對(duì)象被上了鎖,那么該對(duì)象都會(huì)受這個(gè)鎖的控制和影響。 2、選擇悲觀鎖策略,還是樂觀鎖策略,這主要是由應(yīng)用和業(yè)務(wù)需求來確定的。如果你的應(yīng)用和業(yè)務(wù)經(jīng)常會(huì)出現(xiàn)從我看到要修改的記錄的...

oracle 樂觀鎖和悲觀鎖詳細(xì)教程

詳細(xì)介紹了Oracle中樂觀鎖、悲觀鎖的原理及應(yīng)用,并有實(shí)例

基于ORACLE的樂觀鎖實(shí)現(xiàn)原理

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn) ...

繼續(xù)訪問

Oracle之悲觀鎖和樂觀鎖_hys21的博客

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

oracle樂觀鎖和悲觀鎖詳細(xì)教程_oracle的樂觀鎖-Oracle文檔類資源...

內(nèi)部包含oracle百度網(wǎng)盤下載鏈接以及密碼。 oci.dll 12版本全部 資源是從Oracle官方網(wǎng)站下載,已測(cè)試可用 【白雪紅葉】JAVA學(xué)習(xí)技術(shù)棧梳理思維導(dǎo)圖.xmind 樂觀鎖行級(jí)鎖 分布式鎖 分區(qū)排隊(duì) 一致性 一致性算法 paxos zab nwr raft gossip ...

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

為了得到最大的性能,一般數(shù)據(jù)庫都有并發(fā)機(jī)制,不過帶來的問題就是數(shù)據(jù)訪問的沖突。為了解決這個(gè)問題,大多數(shù)數(shù)據(jù)庫用的方法就是數(shù)據(jù)的鎖定。 考慮下面的情況。如果我們先查詢到數(shù)據(jù),然后更新數(shù)據(jù)。這樣會(huì)出現(xiàn)這樣的情況。A線程查詢的時(shí)候,B線程也在查詢,當(dāng)A線程準(zhǔn)備更新的時(shí)候,B線程先獲得 了更新鎖,將這些行鎖定了。A只能等待B更新完。當(dāng)B線程更新完釋放鎖的時(shí)候,A獲得鎖,這時(shí)A會(huì)識(shí)別出字段已經(jīng)

繼續(xù)訪問

Oracle并發(fā)控制中的樂觀鎖

數(shù)據(jù)庫的管理員要分散他們的數(shù)據(jù)庫,以便處理基于Web,B2B,電子商務(wù)的訪問,快速的硬盤讀寫以及更多的資源或許只能解決一部分問題。疲乏的鎖機(jī)制甚至?xí)魅鯎碛泻芎觅Y源的應(yīng)用性能。樂觀鎖可以大大改善具有較多事務(wù)處理的數(shù)據(jù)庫載入性能,比如基于web的客戶端訪問。 悲觀鎖引發(fā)的問題: 大多數(shù)Oracle開發(fā)者已經(jīng)非常熟悉悲觀鎖,即在對(duì)數(shù)據(jù)進(jìn)行更新之前給數(shù)據(jù)加鎖。使用熟悉的SELECT...FOR UP

繼續(xù)訪問

oracle樂觀鎖悲觀鎖學(xué)習(xí)筆記(更新中)_Evaron.Z的博客

首先解釋下樂觀鎖和悲觀鎖的含義 樂觀鎖:樂觀鎖就是認(rèn)為數(shù)據(jù)一般情況下不會(huì)造成沖突,所以在數(shù)據(jù)進(jìn)行提交更新的時(shí)候,才會(huì)正式對(duì)數(shù)據(jù)的沖突與否進(jìn)行檢測(cè),如果發(fā)現(xiàn)沖突了,則返回錯(cuò)誤的信息。 悲觀鎖:悲觀鎖就是對(duì)數(shù)據(jù)的沖突采取一種悲觀的...

【Oracle】樂觀鎖和悲觀鎖_◣NSD◥的博客_oracle悲觀鎖...

樂觀鎖對(duì)應(yīng)于生活中樂觀的人總是想著事情往好的方向發(fā)展,悲觀鎖對(duì)應(yīng)于生活中悲觀的人總是想著事情往壞的方向發(fā)展。這兩種人各有優(yōu)缺點(diǎn),不能不以場(chǎng)景而定說一種人好于另外一種人。 悲觀鎖 ...

Oracle樂觀鎖悲觀鎖

1.樂觀鎖 當(dāng)處理對(duì)象狀態(tài)時(shí)為了防止沖突 例:一個(gè)下訂單的狀態(tài)status a.更新status為1購買,b取得status為1,這時(shí)a要退貨把status改為2. 這時(shí)如果b還按1的狀態(tài)去處理,發(fā)貨了。就出錯(cuò)了。 正確的做法為: 當(dāng)b發(fā)貨時(shí),為了處理并發(fā)臟讀,需要先根據(jù)原status狀態(tài)去更新status為3訂單處理中 int res = update...

繼續(xù)訪問

【轉(zhuǎn)】 Oracle中樂觀鎖定的四種實(shí)現(xiàn)方式

br /Oracle中樂觀鎖定的四種實(shí)現(xiàn)方式br / br /轉(zhuǎn)自 ;br / 更新前在應(yīng)用中存儲(chǔ)所要操作行的“前映像”,更新時(shí)使用存儲(chǔ)的舊記錄來判斷當(dāng)前值是否已經(jīng)改變; 使用一個(gè)特殊的列,這個(gè)列由一個(gè)數(shù)據(jù)庫觸發(fā)器或應(yīng)用程序代碼維護(hù),可以告訴我們記錄的 “版本”; 使用一個(gè)校驗(yàn)和或散列值,這是使用原來的數(shù)據(jù)計(jì)算得出的; 使用新增的 Oracle 10g 特性 ORA_R

繼續(xù)訪問

oracle的悲觀鎖和樂觀鎖

目錄 1 悲觀鎖 1.1 單表 for update 1.2 關(guān)聯(lián)表for update 1.3 解除for update 鎖的占用 1.4 悲觀鎖缺點(diǎn) 2 樂觀鎖 2.1 比對(duì)法 2.2 版本戳 2.3 timestamp型 2.4 例子Demo 問select *from person for update或update perso...

繼續(xù)訪問

Oracle的悲觀鎖和樂觀鎖

為了得到最大的性能,一般數(shù)據(jù)庫都有并發(fā)機(jī)制,不過帶來的問題就是數(shù)據(jù)訪問的沖突。為了解決這個(gè)問題,大多數(shù)數(shù)據(jù)庫用的方法就是數(shù)據(jù)的鎖定。 數(shù)據(jù)的鎖定分為兩種方法,第一種叫做悲觀鎖,第二種叫做樂觀鎖。什么叫悲觀鎖呢,悲觀鎖顧名思義,...

繼續(xù)訪問

oracle鎖機(jī)制之悲觀鎖與樂觀鎖以及for update用法

目錄 1 悲觀鎖 1.1 單表 for update 1.2關(guān)聯(lián)表for update 1.3 悲觀鎖缺點(diǎn) 2樂觀鎖 2.1 比對(duì)法 2.2版本戳 2.3timestamp型 2.4 例子Demo 1 悲觀鎖 所謂的悲觀鎖:顧名思義,就是很悲觀,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人會(huì)修改,所以每次拿數(shù)據(jù)的時(shí)候都會(huì)上鎖。這樣別人拿數(shù)據(jù)的時(shí)候就要等待直到鎖的釋放。 數(shù)據(jù)庫行級(jí)...

繼續(xù)訪問

oracle的樂觀鎖和悲觀鎖

一、問題引出 ① 假設(shè)當(dāng)當(dāng)網(wǎng)上用戶下單買了本書,這時(shí)數(shù)據(jù)庫中有條訂單號(hào)為001的訂單,其中有個(gè)status字段是’有效’,表示該訂單是有效的; ② 后臺(tái)管理人員查詢到這條001的訂單,并且看到狀態(tài)是有效的; ③ 用戶發(fā)現(xiàn)下單的時(shí)候下錯(cuò)了,于是撤銷訂單,假設(shè)運(yùn)行這樣一條SQL: update order_table set status = ‘取消’ whe

繼續(xù)訪問

Oracle鎖定:悲觀與樂觀鎖詳解

Oracle數(shù)據(jù)庫悲觀鎖與樂觀鎖是本文我們主要要介紹的內(nèi)容。有時(shí)候?yàn)榱说玫阶畲蟮男阅埽话銛?shù)據(jù)庫都有并發(fā)機(jī)制,不過帶來的問題就是數(shù)據(jù)訪問的沖突。為了解決這個(gè)問題,大多數(shù)數(shù)據(jù)庫用的方法就是數(shù)據(jù)的鎖定…… 以下是代碼片段: select*fromtestwhereid=10也就是沒有for update這種鎖定數(shù)據(jù)的語句的話,就不會(huì)造成阻塞了。另外一種情況,就是當(dāng)數(shù)據(jù)庫數(shù)據(jù)被鎖定的時(shí)候,也

繼續(xù)訪問

樂觀鎖與悲觀鎖——解決并發(fā)問題

引言 為什么需要鎖(并發(fā)控制)? 在多用戶環(huán)境中,在同一時(shí)間可能會(huì)有多個(gè)用戶更新相同的記錄,這會(huì)產(chǎn)生沖突。這就是著名的并發(fā)性問題。 典型的沖突有: 丟失更新:一個(gè)事務(wù)的更新覆蓋了其它事務(wù)的更新結(jié)果,就是所謂的更新丟失。例如:用戶A把值從6改為2,用戶B把值從2改為6,則用戶A丟失了他的更新。 臟讀:當(dāng)一個(gè)事務(wù)讀取其它完成一半事務(wù)的記錄時(shí),就會(huì)發(fā)生臟讀取。例如:用戶A,B看到的...

繼續(xù)訪問

樂觀鎖和悲觀鎖策略的區(qū)別與實(shí)現(xiàn)

樂觀鎖和悲觀鎖策略的區(qū)別與實(shí)現(xiàn) 1、無論是選擇悲觀鎖策略,還是樂觀鎖策略。如果一個(gè)對(duì)象被上了鎖,那么該對(duì)象都會(huì)受這個(gè)鎖的控制和影響。如果這個(gè)鎖是個(gè)排它鎖,那么其它會(huì)話都不...

繼續(xù)訪問

oracle的共享鎖不起作用,ORACLE中的樂觀鎖、悲觀鎖、共享鎖、排他鎖

一、引入在數(shù)據(jù)庫操作中,如果不同的用戶或者事務(wù)并發(fā)地訪問同一數(shù)據(jù),可能就會(huì)破壞數(shù)據(jù)到完整性,這時(shí)候我們就可以用鎖來保證數(shù)據(jù)的一致性。二、概念1. 悲觀鎖就是很悲觀地任認(rèn)為我每次要修改數(shù)據(jù)時(shí),其他的操作總會(huì)來改變我要修改的數(shù)據(jù),于是就將其加鎖。這樣一來,其他人只能等待我先放開鎖后才能操作數(shù)據(jù)。請(qǐng)看以下的示例。造數(shù):CREATE TABLE test_yyw(id NUMBER(4),name VAR...

繼續(xù)訪問

oracle 鎖定 問題

鎖(lock)機(jī)制用于管理對(duì)共享資源的并發(fā)訪問。 數(shù)據(jù)庫中使用鎖是為了支持對(duì)共享資源進(jìn)行并發(fā)訪問,與此同時(shí)還能提供數(shù)據(jù)完整性和一致性。 在Oracle中,你會(huì)了解到: ? 事務(wù)是每個(gè)數(shù)據(jù)庫的核心,它們是“好東西”。 ? 應(yīng)該延遲到適當(dāng)?shù)臅r(shí)刻才提交。不要太快提交,以避免對(duì)系統(tǒng)帶來壓力。這是因?yàn)?,如果事?wù)很長或很大,一般不會(huì)對(duì)系統(tǒng)有壓力。相應(yīng)的原則是:在必要時(shí)才提交,但是此前不要提

繼續(xù)訪問

最新發(fā)布 oracle數(shù)據(jù)庫加悲觀鎖,Oracle 悲觀鎖跟樂觀鎖

EMPNO ENAME SAL7782 CLARK 2450.007839 KING 5000.007934 MILLER 1300.00在SQLplus中模擬應(yīng)用可能執(zhí)行的綁定調(diào)用,可以利用下面命名:SQL variable empno numberSQL variable ename varchar2(20)SQL var...

繼續(xù)訪問

Oracle 樂觀鎖、悲觀鎖

oracle有悲觀鎖也有樂觀鎖。 悲觀鎖比較安全一些,可以防止丟失更新,但是就是互相等待,影響效率。 一般會(huì)用樂觀鎖,即開始操作時(shí),樂觀的認(rèn)為數(shù)據(jù)不會(huì)被其他人更改,直到提交時(shí)才加鎖檢查。比如在操作的表上加一列,保存?zhèn)€時(shí)間戳,提交時(shí)檢查是不是最新的。不過樂觀鎖失敗的可能性比較大。 樂觀鎖,大多是基于數(shù)據(jù)版本( Version )記錄機(jī)制實(shí)現(xiàn)。

繼續(xù)訪問

oracle樂觀鎖實(shí)例

oracle 悲觀鎖和樂觀鎖

寫評(píng)論

評(píng)論

收藏

點(diǎn)贊

分享

前往CSDN APP閱讀全文

閱讀體驗(yàn)更佳

CSDN

成就一億技術(shù)人

前往

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)行檢測(cè),如果發(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è)例子。首先建立測(cè)試用的數(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ù)沖突檢測(cè)。在樂觀鎖中,我們有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è)是不是你需要的...

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

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

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

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

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

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

4.兩次更新問題(Second lost updates problem):無法重復(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)沒有執(zhí)行任何鎖操作因此并發(fā)事務(wù)并沒有被隔離開

20、鎖是什么?

鎖:在所有的DBMS(數(shù)據(jù)庫管理系統(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í)行操作過程中,鎖定指定的行。

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

表鎖:指在運(yùn)行操作指令過程中,由用戶指定鎖定某張表。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ā)生死鎖。

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

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

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

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

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

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

樂觀鎖:樂觀鎖假設(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)樂觀鎖的方式就是記錄數(shù)據(jù)版本。

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

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

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

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

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

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

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

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

新聞名稱:oracle怎么加樂觀鎖 oracle 如何釋放鎖
文章地址:http://vcdvsql.cn/article8/hhpcop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、外貿(mào)網(wǎng)站建設(shè)關(guān)鍵詞優(yōu)化品牌網(wǎng)站建設(shè)網(wǎng)站策劃全網(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í)需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司