假設某個使用者(假設為A)發出如下的語句更新一條記錄:
SQL> update employees set last_name='HanSijie'
where employee_id=100;
上面的例子,這時A使用者已經發出了更新employee_id為100的記錄的SQL語句。當A還沒有提交之前 ,另外一個使用者D發出下面的語句:
SQL> drop table employees;
由於使用者A還沒有提交所做的事務,因此該事務還沒有結束,其他使用者還不能刪除該表,否則A所發 出的事務就無法正常結束。為了阻止這時使用者D的刪除操作,我們能夠想到的最直觀的方法就是,在執 行刪除表的命令之前,先依次檢查employees表裡的每一條記錄,查看每一條資料行的頭部是否存在鎖 定標記,如果是,則說明當前正有事務在更新該表,刪除表的操作必須等待。
顯然,這種方式會引起很大的效能問題,Oracle不會採用這種方式。實際上,當我們在對 employees表的資料進行更新時,不僅會在資料行的頭部記錄行級鎖,而且還會在表的層級上添加一個 表級鎖。那麼當D使用者要刪除表時,發現employees表上具有一個表級鎖,於是等待。
通過這種在表層級上添加鎖定的方式,我們就能夠比較容易並且高效地(因為不需要掃描表裡的每 一條記錄來判斷在表上是否有DML事務)對鎖定進行管理了。表級鎖共具有五種模式,如下所示。
行級獨佔鎖定(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鎖。在該鎖定模式下,其他使用者不能對錶進行任何 的DML和DDL操作,該表上只能進行查詢。
共用行級獨佔鎖定(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 |
RS、RX、S、SRX、X |
| Insert into …… |
RX |
RS、RX |
| Update …… |
RX |
RS、RX |
| Delete from …… |
RX |
RS、RX |
| Select * from for update |
RS |
RS、RX、S、SRX |
| lock table in row share mode |
RS |
RS、RX、S、SRX |
| lock table in row exclusive mode |
RX |
RS、RX |
| lock table in share mode |
S |
RS、S |
| lock table in share row exclusive mode |
SRX |
RS |
| lock table in exclusive mode |
X |
RS |
對於通過lock table命令主動添加的鎖定來說,如果要釋放它們,只需要發出rollback命令即可。
查看本欄目更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/database/Oracle/