oracle中分爲兩種模式的鎖,一種是排他鎖(X鎖),另外一種是共享所(S鎖).數據庫
鎖是實現併發的主要手段,在數據庫中應用頻繁,但不少都由數據庫自動管理,當事務提交後會自動釋放鎖.編程
Oracle爲了使數據庫實現高度併發訪問,它使用了不一樣類型的鎖來管理併發會話對數據對象的操做.Oracle的鎖按做用對象不一樣分爲以下幾種類型.
這裏主要介紹下經常使用的DML鎖,它主要保證了併發訪問時數據的完整性.它又能夠分爲如下兩種類型的鎖:
1) 行級鎖(TX),也能夠稱爲事務鎖.當修改表中某行記錄時,須要對將要修改的記錄加行級鎖,防止兩個事務同時修改相同記錄,事務結束,該鎖也會釋放,是粒度最細的鎖.該鎖只能屬於排他鎖(X鎖).併發
2) 表級鎖(TM),主要做用書防止在修改表的數據時,表的結構發生變化.例如,會話S在修改表A的數據時,它會獲得表A的TM鎖,而此時將不容許其餘會話對該表進行變動或刪除操做. 該狀況的驗證過程以下:oracle
UPDATE TABLE_NAME SET COLUMN= 'test' WHERE ID = 'id';
此時已經鎖定該表,表級鎖將不容許在事務結束前其餘會話對錶TABLE_NAME進行DDL操做.
其次,在執行DROP TABLE TABLE_NAME
操做,執行後會提示ORA-00054錯誤.
緣由是:
在執行DML操做時,數據庫會先申請數據對象上的共享鎖,防止其餘會話對該對象執行DDL操做。一旦申請成功,則會對將要修改的記錄申請排他鎖,若是此時其餘會話正在修改該記錄,那麼等待其事務結束後再爲修改的記錄加上排他鎖。性能
下表列出了以上5中模式相互之間的兼容關係.其中,✔表示相互兼容,×表示相互不兼容學習
\ | RS | S | RX | SRX | X | |
---|---|---|---|---|---|---|
RS | ✔ | ✔ | ✔ | ✔ | × | |
S | ✔ | ✔ | × | × | × | |
RX | ✔ | × | ✔ | ✔ | × | |
SRX | ✔ | × | × | × | × | |
X | × | × | × | × | × |
下面所示是Oracle中的各類SQL語句所產生的表級鎖模式以及容許的鎖定模式狀況的彙總.code
SQL語句 | 表鎖模式 | RS | S | RX | SRX | X |
---|---|---|---|---|---|---|
SELECT ...FROM table | NONE | Y | Y | Y | Y | Y |
INSERT INTO ... | RX | Y | N | Y | N | N |
UPDATE table ... | RX | Y | N | Y | N | N |
DELETE FROM table ... | RX | Y | N | Y | N | N |
SELECT * FROM table FOR UPDATE | RX | Y | N | Y | N | N |
LOCK TABLE table IN ROW SHARE MODE | RS | Y | Y | Y | Y | N |
LOCK TABLE table IN ROW EXCLUSIVE MODE | RX | Y | N | Y | N | N |
LOCK TABLE table IN SHARE MODE | S | Y | N | N | N | N |
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE | SRX | Y | N | N | N | N |
LOCK TABLE table IN EXCLUSIVE MODE | X | N | N | N | N | N |
在Oracle中除了執行DML時自動爲表添加TM鎖外,也能夠主動地爲表添加TM鎖,語法以下:對象
LOCK TABLE [schema.] table IN [EXCLUSIVE] [SHARE] [ROW EXCLUSIVE] [SHARE ROW EXCLUSIVE] [ROW SHARE* | SHARE UPDATE*] MODE [NOWAIT]
DDL鎖也能夠稱爲數據字典鎖,主要做用是保護模式中對象的結構.當執行DDL操做時首先Oracle會自動地隱式提交一次事務,而後自動地給處理對象加上鎖;當DDL結束時,Oracle會隱式地提交事務並釋放DDL鎖.與DML不一樣的是,用戶不能顯式的要求使用DDL鎖.事務
DDL鎖分爲以下3類:資源
在某些狀況下因爲佔用的資源不能及時釋放,而形成鎖等待,也能夠叫鎖衝突.鎖等待會嚴重地影響數據庫性能和平常工做.
例如當一個會話修改表A的記錄時,它會對該記錄加鎖,而此時若是另外一個會話也來修改此記錄,那麼第二個會話將因得不到排他鎖而一直等待,此時會出現執行SQL時數據庫長時間沒有響應的現象.直到第一個會話把事務提交,釋放鎖,第二個會話才能對數據進行操做.
下面爲你們示例鎖等待現象:
UPDATE PRODUCTINFO SET ORIGIN = '修改1' WHERE PRODUCTID = 1;
此時雖然提示已更新,但事務並無提交.接下來進行第二步操做.
UPDATE PRODUCTINFO SET ORIGIN = '修改2' WHERE PRODUCTID = 1;
此時執行效果不會提示已更新,而是一直等待.
此時的狀況是由於第一個會話封鎖了該記錄,但事務沒有結束,鎖不會釋放,而這時第二個會話也要修改同一條記錄,但它缺沒有辦法得到排他鎖,因此只能等待.若是第一個會話修改數據的事務結束,那麼第二個會話會結束等待.及時地結束事務是解決鎖等待狀況發生的有效方法.
死鎖的發生和鎖等待不一樣,它是鎖等待的一個特例,一般發生在兩個或者多個會話之間.假設一個會話想要修改兩個資源對象,能夠是表也能夠是字段,修改這兩個資源的操做在一個事務當中,當它修改第一個對象時須要對其鎖定,而後等待第二個對象,這時若是另一個會話也須要修改這兩個資源對象,而且已經得到對第二個對象的鎖定,那麼就會出現死鎖,由於當前會話鎖定了第一個對象等待第二個對象,而另外一個會話鎖定了第二個對象等待第一個對象.這樣,兩個會話都不能獲得想要獲得的對象,因而出現死鎖.
這裏例子就不在展現,你們能夠自行試一試.實際開發中出現死鎖狀況大體有如下幾種緣由: