statement: 一個(gè)SQL語(yǔ)句。
session: 一個(gè)由ORACLE用戶產(chǎn)生的連接,一個(gè)用戶可以產(chǎn)生多個(gè)SESSION ,但相互之間是獨(dú)立的。
transaction:所有的改變都可以劃分到transaction里,一個(gè) transaction包含一個(gè)或多個(gè)SQL。當(dāng)一個(gè)SESSION建立的時(shí)候就是一個(gè)TRANSACTION開(kāi)始的時(shí)刻,此后transaction的 開(kāi)始和結(jié)束由DCL控制,也就是每個(gè)COMMIT/ROLLBACK都標(biāo)示著一個(gè)transaction的結(jié)束。
consistency:是對(duì)于statement級(jí)別而不是transaction級(jí)別來(lái)說(shuō)的。sql statement 得到的數(shù)據(jù)都是以sql statement開(kāi)始的IMAGE。
LOCK的基本情況:
update, insert ,delete, select ... for update會(huì)LOCK相應(yīng)的ROW 。
只有一個(gè)TRANSACTION可以LOCK相應(yīng)的行,也就是說(shuō)如果一個(gè)ROW已經(jīng)LOCKED了,那就不能被其他TRANSACTION所LOCK了。
LOCK由statement產(chǎn)生但卻由TRANSACTION結(jié)尾(commit,rollback),也就是說(shuō)一個(gè)SQL完成后LOCK還會(huì)存在,只有在COMMIT/ROLLBACK后才會(huì)RELEASE。
SELECT.... FOR UPDATE [OF cols] [NOWAIT]; OF cols SELECT cols FROM tables [WHERE...] FOR UPDATE [OF cols] [NOWAIT];
|
前面的FOR UPDATE省略,下面我們來(lái)講一下OF。
transaction A運(yùn)行 select a.object_name,a.object_id from wwm2 a,wwm3 b 2 where b.status='VALID' and a.object_id=b.object_id 3* for update of a.status
|
則transaction B可以對(duì)b表wwm3的相應(yīng)行進(jìn)行DML操作,但不能對(duì)a表wwm2相應(yīng)行進(jìn)行DML操作.
反一下看看。
transaction A運(yùn)行 select a.object_name,a.object_id from wwm2 a,wwm3 b 2 where b.status='VALID' and a.object_id=b.object_id 3* for update of b.status
|
則transaction B可以對(duì)a表wwm2的相應(yīng)行進(jìn)行DML操作,但不能對(duì)b表wwm3相應(yīng)行進(jìn)行DML操作.
也就是說(shuō)LOCK的還是行,只是如果不加OF的話會(huì)對(duì)所有涉及的表LOCK的,加了OF后只會(huì)LOCK OF 字句所在的TABLE.
NOWAIT(如果一定要用FOR UPDATE,我更建議加上NOWAIT)
當(dāng)有LOCK沖突時(shí)會(huì)提示錯(cuò)誤并結(jié)束STATEMENT而不是在那里等待.返回錯(cuò)誤是"ORA-00054: resource busy and acquire with NOWAIT specified"
另外如下用法也值得推薦,應(yīng)該酌情考慮使用。
5秒后會(huì)出現(xiàn)提示:
ORA-30006: resource busy; acquire with WAIT timeout expired FOR UPDATE NOWAIT SKIP LOCKED;
|
出現(xiàn)提示:
no rows selected TABLE LOCKS LOCK TABLE table(s) IN EXCLUSIVE MODE [NOWAIT];
|
同樣也是在transaction結(jié)束時(shí)才會(huì)釋放lock。
DEADLOCK:
transaction a lock rowA , then transaction b lock rowB then transaction a tries to lock rowB, and transaction b tries to lock rowA
|
也就是說(shuō)兩個(gè)transaction都相互試圖去lock對(duì)方已經(jīng)lock的ROW,都在等待對(duì)方釋放自己的lock,這樣就使死鎖。另外,deadlock也會(huì)有600提示。
使用說(shuō)明
Select…For Update語(yǔ)句的語(yǔ)法與select語(yǔ)句相同,只是在select語(yǔ)句的后面加FOR UPDATE [NOWAIT]子句。
該語(yǔ)句用來(lái)鎖定特定的行(如果有where子句,就是滿足where條件的那些行)。當(dāng)這些行被鎖定后,其他會(huì)話可以選擇這些行,但不能更改或刪除這些行,直到該語(yǔ)句的事務(wù)被commit語(yǔ)句或rollback語(yǔ)句結(jié)束為止。
如 圖20.51所示,左上角的會(huì)話用Select…For Update語(yǔ)句鎖定了Department表中DeptNo='01'的行,右上角的會(huì)話說(shuō)明其他會(huì)話不可以繼續(xù)更改該行上的數(shù)據(jù)。從OEM中的鎖的信 息可以看出,Select…For Update語(yǔ)句所加的鎖與update語(yǔ)句所加的鎖相同:一個(gè)行級(jí)別的EXCLUSIVE鎖(說(shuō)明多個(gè)事務(wù)不能同時(shí)操作同一行)、一個(gè)表級(jí)別的ROW EXCLUSIVE鎖。
圖20.51 Select…For Update語(yǔ)句鎖定了符合where條件的行
如圖20.52所示,左上角的會(huì)話用Update語(yǔ)句鎖定了Department表中DeptNo='01'的行,右上角的會(huì)話說(shuō)明其他會(huì)話不可以用Select…For Update語(yǔ)句繼續(xù)鎖定該行。
圖20.52 Select…For Update語(yǔ)句被其他會(huì)話阻塞了
如 圖20.53所示,左上角的會(huì)話用Update語(yǔ)句鎖定了Department表中DeptNo='01'的行,右上角的會(huì)話說(shuō)明其他會(huì)話不可以用 Select…For Update NOWAIT語(yǔ)句繼續(xù)鎖定該行,且會(huì)立即返回一個(gè)錯(cuò)誤提示“ORA-00054: 資源正忙, 但指定以 NOWAIT 方式獲取資源”,而不需要等待加鎖成功。
圖20.53 如果加鎖不成功,則Select…For Update NOWAIT語(yǔ)句就會(huì)立即返回錯(cuò)誤提示
可 以看出,如果僅僅用update語(yǔ)句來(lái)更改數(shù)據(jù)時(shí),可能會(huì)因?yàn)榧硬簧湘i而沒(méi)有響應(yīng)地、莫名其妙地等待,但如果在此之前,先用Select…For Update NOWAIT語(yǔ)句將要更改的數(shù)據(jù)試探性地加鎖,