Oracle事務之一:鎖和隔離


   . 事務概述

      事務管理是數據庫處理的核心。數據庫既要保證用戶能並發地執行事務,還要保證數據庫的一致性。

      當第一條可執行的SQL開始執行,就隱形地開始了一個事務,直到遇到下面的幾種情況:

      1.Commit:提交事務。

      2.RollBack:回滾。

      3.DDL語句:執行和提交DDL語句結果前首先提交當前所有DML語句,成為隱式提交。

      4.程序正常退出:自動提交。

      5.不正常的程序失敗:隱式回滾。

 

.事務特性

      事務的四個特性:A(原子性)、C(一致性)、I(隔離性)、D(永久性)。

 

.事務隔離級別

      數據庫並發的事務會帶來以下四個問題:臟讀,更新丟失,不可重復讀,幻讀。

      對於上面這四個問題,可以通過設置不同的隔離級別來避免。

      首先是未提交讀。這種並發性最高,但是仍會產生以上四個問題。

      第二種是已提交讀。這是Oracle的默認隔離級別,查詢語句只能看到已提交的數據。隔離的已提交讀能保證在訪問特定的行時,該行的數據保持不變。所以,這個級別可以防止臟讀和更新丟失。

      第三種是可重復讀。保證讀一致性。

      最后一種是串行。隔離級別最高,但數據庫的並發性受到了很大的限制。對DML操作的數據會放置一個寫鎖,別的涉及DML的操作不得不等待鎖解除。可以避免上面的四個問題,但在現實中不可用。

 

.多版本讀一致性

    Oracle通過提供多版本來保證一致性,這個是通過撤銷段來實現的。

      Oracle默認提供語句級讀一致性,也就是說,查詢只能看到它開始前已提交的數據,看不到執行過程中提交的數據。

    事務級讀一致性就是可以保證在一個事務中的所有查詢一致性。在這種情況下,每個事務中的語句都從同一個時間點來看數據,這個時間點就是事務開始時。它可以避免出現不可重復讀和幻讀。

 

.鎖的類型

      根據保護的對象不同,Oracle數據庫鎖可以分為以下幾大類:DML鎖(data locks,數據鎖),用於保護數據的完整性;DDL鎖(dictionary locks,字典鎖),用於保護數據庫對象的結構,如表、索引等的結構定義;內部鎖和閂(internal locks and latches),保護數據庫的內部結構。

      DML鎖的目的在於保證並發情況下的數據完整性,在Oracle數據庫中,DML鎖主要包括TM鎖和TX鎖,其中TM鎖稱為表級鎖,TX鎖稱為事務鎖或行級鎖。

      Oracle執行DML語句時,系統自動在所要操作的表上申請TM類型的鎖。當TM鎖獲得后,系統再自動申請TX類型的鎖,並將實際鎖定的數據行的鎖標志位進行置位。這樣在事務加鎖前檢查TX鎖相容性時就不用再逐行檢查鎖標志,而只需檢查TM鎖模式的相容性即可,大大提高了系統的效率。TM鎖包括了SSSXSX 等多種模式,在數據庫中用06來表示。不同的SQL操作產生不同類型的TM鎖。

      在數據行上只有X鎖(排他鎖)。在 Oracle數據庫中,當一個事務首次發起一個DML語句時就獲得一個TX鎖,該鎖保持到事務被提交或回滾。當兩個或多個會話在表的同一條記錄上執行 DML語句時,第一個會話在該條記錄上加鎖,其他的會話處於等待狀態。當第一個會話提交后,TX鎖被釋放,其他會話才可以加鎖。

      下面是各種鎖。

行級排他鎖(Row Exclusive,簡稱RX鎖)

      當我們進行DML時會自動在被更新的表上添加RX鎖,或者也可以通過執行lock命令顯式的在表上添加RX鎖。在該鎖定模式下,允許其他的事務通過DML語句修改相同表里的其他數據行,或通過lock命令對相同表添加RX鎖定,但是不允許其他事務對相同的表添加排他鎖(X鎖)。

行級共享鎖(Row Shared,簡稱RS鎖)

     通常是通過select from for update語句添加的,同時該方法也是我們用來手工鎖定某些記錄的主要方法。比如,當我們在查詢某些記錄的過程中,不希望其他用戶對查詢的記錄進行更新操作,則可以發出這樣的語句。當數據使用完畢以后,直接發出rollback命令將鎖定解除。當表上添加了RS鎖定以后,不允許其他事務對相同的表添加排他鎖,但是允許其他的事務通過DML語句或lock命令鎖定相同表里的其他數據行。

共享鎖(Share,簡稱S鎖)

     通過lock table in share mode命令添加該S鎖。在該鎖定模式下,不允許任何用戶更新表。但是允許其他用戶發出select from for update命令對表添加RS鎖。

排他鎖(Exclusive,簡稱X鎖)

     通過lock table in exclusive mode命令添加X鎖。在該鎖定模式下,其他用戶不能對表進行任何的DMLDDL操作,該表上只能進行查詢。

共享行級排他鎖(Share Row Exclusive,簡稱SRX鎖)

     通過lock table in share row exclusive mode命令添加SRX鎖。該鎖定模式比行級排他鎖和共享鎖的級別都要高,這時不能對相同的表進行DML操作,也不能添加共享鎖。

     這五種模式的TM鎖的兼容關系如下表所示(√表示互相兼容的請求;×表示互相不兼容的請求;N/A表示沒有鎖定請求):

-

S

X

RS

RX

SRX

N/A

S

×

×

×

X

×

×

×

×

×

RS

×

RX

×

×

×

SRX

×

×

×

×

N/A

      從前面的描述中可以看到,我們不僅可以通過發出DML語句的方式,由Oracle自動在表級別上添加TM鎖。我們還可以通過發出lock table命令主動地在表級別上添加TM鎖,並在該命令中可以指定不同的鎖定模式,其命令格式如下所示:

lock table in [row share][row exclusive]

[share][share row exclusive][exclusive] mode;

      Oracle數據庫中的各SQL語句所產生的表級鎖的情況進行匯總,如下表所示:

SQL語句

表鎖定模

允許的表鎖定模式

Select * from ……

RS

RSRXSSRXX

Insert into ……

RX

RSRX

Update ……

RX

RSRX

Delete from ……

RX

RSRX

Select * from for update

RS

RSRXSSRX

lock table in row share mode

RS

RSRXSSRX

lock table in row exclusive mode

RX

RSRX

lock table in share mode

S

RSS

lock table in share row exclusive mode

SRX

RS

lock table in exclusive mode

X

RS

    對於通過lock table命令主動添加的鎖定來說,如果要釋放它們,只需要發出rollback命令即可。

 

 六.我學習中的疑惑和解答

疑惑:既然已經有了鎖,為什么還要有隔離級別?

解答:在csdn上找到一個答案,地址:http://topic.csdn.net/u/20100713/12/7e6e102e-03f9-420e-81b3-527ab4437792.html

具體:

事務隔離級別是並發控制的整體解決方案,其實際上是綜合利用各種類型的鎖和行版本控制,來解決並發問題。
鎖是數據庫並發控制的內部機制,是基礎。當然,數據庫同時還會利用行版本控制(SQL Server 2005 及以上)來進行並發控制;在數據庫內部還使用閂(latch),互斥(mutex)等機制處理內部資源(如,緩存)的並發訪問。
對用戶來說,只有當事務隔離級別無法解決一些並發問題和需求時,才有必要在語句中手動設置鎖。不適當的設置鎖,可能會導致嚴重的阻塞和死鎖。建議,只有在完全了解鎖機制的情況下,才可以在語句中手動設置鎖,否則應該使用事務隔離級別。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM