當前位置:首頁 » 數據倉庫 » 資料庫系統為其分配的鎖類型為
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

資料庫系統為其分配的鎖類型為

發布時間: 2023-02-23 06:44:33

『壹』 Oracle中的鎖

>>>>>這些是基礎,必須掌握:鎖定的概念:鎖定是資料庫用來控制共享資源並發布訪問的機制。在多用戶環境下,多個用戶可同時訪問相同的數據。Oracle 提供鎖以確保在多用戶環境下數據的完整性和一致性。在提交或回滾事務之前,Oracle 會鎖定正被修改的數據。在用戶完成或回滾事務之後,鎖會自動釋放。只有在提交或回滾事物之後,其他用戶才可以更新這些數據。鎖的兩種級別為:行級鎖和表級鎖。行級鎖主要用於特定的行,表級鎖主要用於整個表,下面我就行級鎖和表級鎖來個說明:行級鎖行級鎖只對用戶正在訪問的行進行鎖定。如果該用戶正在修改某行,那麼其他用戶就可以更新同一表中該行之外的數據。例如:如果用戶1正在更新Jobs 表中的第一行,則用戶2可以同時修改該表中的第二行。也就是說除了該表中的第一行,其他用戶可以修改任意行,但是第一行的數據其他用戶只能select。行級鎖是一種排他鎖,防止其他事務修改此行,但是不會阻止讀取此行的操作。在使用INSERT、UPDATE、DELETE 和SELECT…FOR UPDATE 等 語句時,Oracle 會自動應用行級鎖鎖定。SELECT...FOR UPDATE 語句允許用戶每次選擇多行記錄進行更新,這些記錄會被鎖定,且只能由發起查詢的用戶進行編輯。只有在回滾或提交事務之後,鎖定才會釋放,其他用戶才可以編輯這些記錄。SELECT...FOR UPDATE 語句的語法如下: SELECT ... FOR UPDATE [OF column_list][WAIT n|NOWAIT];其中:OF 子句用於指定即將更新的列,即鎖定行上的特定列。WAIT 子句指定等待其他用戶釋放鎖的秒數,防止無限期的等待。「使用FOR UPDATE WAIT」子句的優點如下:⒈防止無限期地等待被鎖定的行;⒉允許應用程序中對鎖的等待時間進行更多的控制。⒊對於互動式應用程序非常有用,因為這些用戶不能等待不確定舉例:比如一個用戶在sql PLUS下輸入這條語句:SQL>SELECT * FROM order_master WHERE vencode='V002' FOR UPDATE;此時再開啟一個SQL PLUS,以相同的用戶登陸,執行下面的命令。SQL<> SELECT * FROM order_master WHERE vencode='V02' FOR UPDATE WAIT 5;由於要更新的行已經被鎖定,上述命令在等待5秒鍾之後返回,並給出如下的錯誤信息:ERROR 位於第1行;ORA-30006;資源已被佔用;執行操作時出現WAIT超時。PS:再開啟的SQL PLUS 是以相同用戶登陸的,用其他用戶登陸更是不可能。表級鎖表級鎖被鎖定的表,暫時放在內存中,不提交不進去資料庫,也就是說,多個用戶在同一時間,同時修改同一個表的同一行時,同時點提交,但是還是按隨機的先後被提交進資料庫,而不是同時被提交,而是先隨機存儲後,被再次提交的覆蓋。表級鎖將保護表數據,在事務處理過程中,表級鎖會限制對整個表的訪問。可以使用LOCK TABLE 語句顯示地鎖定表。表級鎖用來限制對表執行添加、更新和刪除等修改操作。鎖定表的語法如下:LOCK TABLE <table_name> IN <lock_mode> MODE [NOWAIT];其中:lock_mode 是鎖定的模式。NOWAIT 關鍵字用於防止無限期的等待其他用戶釋放鎖。表級鎖的模式包括以下內容:行共享 (ROW SHARE, RS): 允許其他用戶訪問和鎖定該表,但是禁止排他鎖定整個表。行共享鎖鎖定後,在同一時刻,不同用戶可以對同一個表中的被行共享鎖鎖定後的該行,具備增、刪、改、查的功能。行排他(ROW EXCLUSIVE, RX):與行共享模式相同,同時禁止其他用戶在此表上使用共享鎖。使用SELECT...FOR UPDATE 語句會在表上自動應用排他鎖。被行排他後,其他用戶不能同時修改該行,但是可以插入行,可以查詢該行,其他用戶也不能再在該表上對此行進行排他。共享(SHARE, S):共享鎖將鎖定表,僅允許其他用戶查詢表中的行,但不允許插入、更新或刪除行。多個用戶可以同時在同一個表中放置共享鎖,即允許資源共享,因此得名「共享鎖」。例如,如果用戶每天都需要在結帳時更新日銷售表,則可以在更改該表時使用共享鎖以確保數據的一致性。也就是說該表只能查,其他用戶想修改表中行的數據,只需要對該表進行共享鎖。共享行排他(SHARE ROW EXCLUSIVE , SPX):執行比共享表更多的限制。防止其他事務在表上應用共享鎖、共享行排他鎖以及排他鎖。共享行排他是除了該行以外的其他行也不能增、刪、改。只能在此表中加低級表。要是想在該表中更改其他行的數據,就只有其他用戶對該行進行共享行排他鎖,也僅僅只能修改被這個用戶鎖定的行,而其他的行也修改不了。排他(EXCLUSIVE,E):對表執行最大限制。除了允許其他用戶查詢該表的記錄,排他鎖防止其他事務對表做任何更改或在表上應用任何類型的鎖。這個鎖應該叫鎖中之王,他鎖住了的話,其他用戶就只有查詢的功能了,就別想在該表中干別的事了。BTW:在能加很多鎖的表中,如果第一個用戶對該表鎖定時,沒有使用「NOWAIT」語句,是需要第一個用戶對該表COMMIT或ROLLBACK 命令釋放鎖定後,其他用戶才能對該表進行鎖定。如果其他用戶違反了該條,就會無期限的等待。。。。SQL> LOCK TABLE order_mater IN SHARE MODE;而使用下面的語句就可以很少的預防這種情況的存在:SQL> LOCK TBALE order_mater IN SHARE MODE NOWAIT;>>>>>這是些擴展的內容,供大家參考
1 引言—資料庫鎖的基本概念 為了確保並發用戶在存取同一資料庫對象時的正確性(即無丟失修改、可重復讀、不讀「臟」數據),資料庫中引入了鎖機制。基本的鎖類型有兩種:排它鎖(Exclusive locks記為X鎖)和共享鎖(Share locks記為S鎖)。 排它鎖:若事務T對數據D加X鎖,則其它任何事務都不能再對D加任何類型的鎖,直至T釋放D上的X鎖;一般要求在修改數據前要向該數據加排它鎖,所以排它鎖又稱為寫鎖。 共享鎖:若事務T對數據D加S鎖,則其它事務只能對D加S鎖,而不能加X鎖,直至T釋放D上的S鎖;一般要求在讀取數據前要向該數據加共享鎖,所以共享鎖又稱為讀鎖。 2 Oracle 多粒度封鎖機制介紹 根據保護對象的不同,Oracle資料庫鎖可以分為以下幾大類: (1) DML lock(data locks,數據鎖):用於保護數據的完整性; (2) DDL lock(dictionary locks,字典鎖):用於保護資料庫對象的結構(例如表、視圖、索引的結構定義); (3) internal locks 和l a t c h es(內部鎖與閂):保護內部資料庫結構; (4) distributed locks(分布式鎖):用於OPS(並行伺服器)中; (5) PCM locks(並行高速緩存管理鎖):用於OPS(並行伺服器)中。 本文主要討論DML(也可稱為data locks,數據鎖)鎖。從封鎖粒度(封鎖對象的大小)的角度看,Oracle DML鎖共有兩個層次,即行級鎖和表級鎖。 2.1 Oracle的TX鎖(行級鎖、事務鎖) 許多對Oracle不太了解的技術人員可能會以為每一個TX鎖代表一條被封鎖的數據行,其實不然。TX的本義是Transaction(事務),當一個事務第一次執行數據更改(Insert、Update、Delete)或使用SELECT… FOR UPDATE語句進行查詢時,它即獲得一個TX(事務)鎖,直至該事務結束(執行COMMIT或ROLLBACK操作)時,該鎖才被釋放。所以,一個TX鎖,可以對應多個被該事務鎖定的數據行。 在Oracle的每行數據上,都有一個標志位來表示該行數據是否被鎖定。Oracle不象其它一些DBMS(資料庫管理系統)那樣,建立一個鏈表來維護每一行被加鎖的數據,這樣就大大減小了行級鎖的維護開銷,也在很大程度上避免了其它資料庫系統使用行級封鎖時經常發生的鎖數量不夠的情況。數據行上的鎖標志一旦被置位,就表明該行數據被加X鎖,Oracle在數據行上沒有S鎖。

2.2 TM鎖(表級鎖) 2.2.1 意向鎖的引出 表是由行組成的,當我們向某個表加鎖時,一方面需要檢查該鎖的申請是否與原有的表級鎖相容;另一方面,還要檢查該鎖是否與表中的每一行上的鎖相容。比如一個事務要在一個表上加S鎖,如果表中的一行已被另外的事務加了X鎖,那麼該鎖的申請也應被阻塞。如果表中的數據很多,逐行檢查鎖標志的開銷將很大,系統的性能將會受到影響。為了解決這個問題,可以在表級引入新的鎖類型來表示其所屬行的加鎖情況,這就引出了「意向鎖」的概念。 意向鎖的含義是如果對一個結點加意向鎖,則說明該結點的下層結點正在被加鎖;對任一結點加鎖時,必須先對它的上層結點加意向鎖。如:對表中的任一行加鎖時,必須先對它所在的表加意向鎖,然後再對該行加鎖。這樣一來,事務對表加鎖時,就不再需要檢查表中每行記錄的鎖標志位了,系統效率得以大大提高。 2.2.2 意向鎖的類型 由兩種基本的鎖類型(S鎖、X鎖),可以自然地派生出兩種意向鎖: 意向共享鎖(Intent Share Lock,簡稱IS鎖):如果要對一個資料庫對象加S鎖,首先要對其上級結點加IS鎖,表示它的後裔結點擬(意向)加S鎖; 意向排它鎖(Intent Exclusive Lock,簡稱IX鎖):如果要對一個資料庫對象加X鎖,首先要對其上級結點加IX鎖,表示它的後裔結點擬(意向)加X鎖。 另外,基本的鎖類型(S、X)與意向鎖類型(IS、IX)之間還可以組合出新的鎖類型,理論上可以組合出4種,即:S+IS,S+IX,X+IS,X+IX,但稍加分析不難看出,實際上只有S+IX有新的意義,其它三種組合都沒有使鎖的強度得到提高(即:S+IS=S,X+IS=X,X+IX=X,這里的「=」指鎖的強度相同)。所謂鎖的強度是指對其它鎖的排斥程度。 這樣我們又可以引入一種新的鎖的類型。 共享意向排它鎖(Shared Intent Exclusive Lock,簡稱SIX鎖) :如果對一個資料庫對象加SIX鎖,表示對它加S鎖,再加IX鎖,即SIX=S+IX。例如:事務對某個表加SIX鎖,則表示該事務要讀整個表(所以要對該表加S鎖),同時會更新個別行(所以要對該表加IX鎖)。 這樣資料庫對象上所加的鎖類型就可能有5種:即S、X、IS、IX、SIX。 具有意向鎖的多粒度封鎖方法中任意事務T要對一個資料庫對象加鎖,必須先對它的上層結點加意向鎖。申請封鎖時應按自上而下的次序進行;釋放封鎖時則應按自下而上的次序進行;具有意向鎖的多粒度封鎖方法提高了系統的並發度,減少了加鎖和解鎖的開銷。 2.2.3 Oracle的TM鎖(表級鎖) Oracle的DML鎖(數據鎖)正是採用了上面提到的多粒度封鎖方法,其行級鎖雖然只有一種(即X鎖),但其TM鎖(表級鎖)類型共有5種,分別稱為共享鎖(S鎖)、排它鎖(X鎖)、行級共享鎖(RS鎖)、行級排它鎖(RX鎖)、共享行級排它鎖(SRX鎖),與上面提到的S、X、IS、IX、SIX相對應。需要注意的是,由於Oracle在行級只提供X鎖,所以與RS鎖(通過SELECT … FOR UPDATE語句獲得)對應的行級鎖也是X鎖(但是該行數據實際上還沒有被修改),這與理論上的IS鎖是有區別的。 下表為Oracle資料庫TM鎖的相容矩陣(Y=Yes,表示相容的請求; N=No,表示不相容的請求;-表示沒有加鎖請求):
T2
T1 S X RS RX SRX -
----------------------------------------------------
S Y N Y N N Y
X N N N N N Y
RS Y N Y Y Y Y
RX N N Y Y N Y
SRX N N Y N N Y
- Y Y Y Y Y Y
表一:Oracle資料庫TM鎖的相容矩陣 一方面,當Oracle執行SELECT…FOR UPDATE、INSERT、UPDATE、DELETE等DML語句時,系統自動在所要操作的表上申請表級RS鎖(SELECT…FOR UPDATE)或RX鎖(INSERT、UPDATE、DELETE),當表級鎖獲得後,系統再自動申請TX鎖,並將實際鎖定的數據行的鎖標志位置位(指向該TX鎖);另一方面,程序或操作人員也可以通過LOCK TABLE語句來指定獲得某種類型的TM鎖。下表總結了Oracle中各SQL語句產生TM鎖的情況: SQL語句 表鎖模式 允許的鎖模式
-------------------------------------------------------------------------------------------------
Select * from table_name…… 無 RS、RX、S、SRX、X
Insert into table_name…… RX RS、RX
Update table_name…… RX RS、RX
Delete from table_name…… RX RS、RX
Select * from table_name for update RS RS、RX、S、SRX
lock table table_name in row share mode RS RS、RX、S、SRX
lock table table_name in row exclusive mode RX RS、RX
lock table table_name in share mode S RS、S
lock table table_name in share row exclusive mode SRX RS
lock table table_name in exclusive mode X 無

『貳』 ORACLE里幾種鎖模式

ORACLE鎖具體分為以下幾類:

1.按用戶與系統劃分,可以分為自動鎖與顯示鎖

自動鎖:當進行一項資料庫操作時,預設情況下,系統自動為此資料庫操作獲得所有有必要的

顯示鎖:某些情況下,需要用戶顯示的鎖定資料庫操作要用到的數據,才能使資料庫操作執行得更好,顯示鎖是用戶為資料庫對象設定的。

2.按鎖級別劃分,可分為共享鎖與排它鎖

共享鎖:共享鎖使一個事務對特定資料庫資源進行共享訪問——另一事務也可對此資源進行訪問或獲得相同共享鎖。共享鎖為事務提供高並發性,但如拙劣的事務設計+共享鎖容易造成死鎖或數據更新丟失。

排它鎖:事務設置排它鎖後,該事務單獨獲得此資源,另一事務不能在此事務提交之前獲得相同對象的共享鎖或排它鎖。

3.按操作劃分,可分為DML鎖、DDL鎖

+DML鎖又可以分為,行鎖、表鎖、死鎖

-行鎖:當事務執行資料庫插入、更新、刪除操作時,該事務自動獲得操作 表中操作行的排它鎖。

-表級鎖:當事務獲得行鎖後,此事務也將自動獲得該行的表鎖(共享鎖),以防止其它事務進行DDL語句影響記錄行的更新。事務也可以在進行 過程中獲得共享鎖或排它鎖,只有當事務顯示使用LOCK TABLE語 句顯示的定義一個排它鎖時,事務才會獲得表上的排它鎖,也可使用
LOCK TABLE顯示的定義一個表級的共享鎖(LOCK TABLE具體用法請參 考相關文檔)。
-死鎖:當兩個事務需要一組有沖突的鎖,而不能將事務繼續下去的話,就 出現死鎖。
如事務1在表A行記錄#3中有一排它鎖,並等待事務2在表A中記錄#4 中排它鎖的釋放,而事務2在表A記錄行#4中有一排它鎖,並等待事務 1在表A中記錄#3中排它鎖的釋放,事務1與事務2彼此等待,因此就造 成了死鎖。死鎖一般是因拙劣的事務設計而產生。
死鎖只能使用SQL下:alter system kill session 'sid,serial#';
或者使用相關操作系統kill進程的命令,如UNIX下kill -9 sid,或者 使用其它工具殺掉死鎖進程。

+DDL鎖又可以分為:排它DDL鎖、共享DDL鎖、分析鎖
-排它DDL鎖:創建、修改、刪除一個資料庫對象的DDL語句獲得操作對象的 排它鎖。
如使用alter table語句時,為了維護數據的完成性、一致性、
合法性,該事務獲得一排它DDL鎖。

-共享DDL鎖:需在資料庫對象之間建立相互依賴關系的DDL語句通常需共享
獲得DDL鎖。
如創建一個包,該包中的過程與函數引用了不同的資料庫表,
當編譯此包時,該事務就獲得了引用表的共享DDL鎖。

-分析鎖:ORACLE使用共享池存儲分析與優化過的SQL語句及PL/SQL程序,使
運行相同語句的應用速度更快。一個在共享池中緩存的對象獲得
它所引用資料庫對象的分析鎖。分析鎖是一種獨特的DDL鎖類型,
ORACLE使用它追蹤共享池對象及它所引用資料庫對象之間的依賴 關系。當一個事務修改或刪除了共享池持有分析鎖的資料庫對象
時,ORACLE使共享池中的對象作廢,下次在引用這條SQL/PLSQL語 句時,ORACLE重新分析編譯此語句。

4.內部閂鎖

內部閂鎖:這是ORACLE中的一種特殊鎖,用於順序訪問內部系統結構。
當事務需向緩沖區寫入信息時,為了使用此塊內存區域, ORACLE首先必須取得這塊內存區域的閂鎖,才能向此塊內存寫入
信息。

『叄』 資料庫中x封鎖與s封鎖有什麼區別

資料庫中X封鎖和S封鎖的區別如下:

1、兩種封鎖共享上的區別:

排它鎖(記為X鎖),又叫寫鎖;共享鎖(記為S鎖),又叫讀鎖。讀鎖是共享的,或者說是相互不阻塞的。寫鎖是排他的,一個寫鎖會阻塞其他的寫鎖和讀鎖。

2、讀取許可權上的區別:

若事務T對數據對象A加上X鎖,事務T可以讀A也可以修改A,其他事務不能再對A加任何鎖,直到T釋放A上的鎖。這保證了其他事務在T釋放A上的鎖之前不能再讀取和修改A。

3、修改許可權上的區別

若事務T對數據對象A加上S鎖,則事務T可以讀A但不能修改A,其他事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。這保證了其他事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改。

(3)資料庫系統為其分配的鎖類型為擴展閱讀:

資料庫中封鎖的對象:

封鎖是實現並發控制的一個非常重要的技術。DBMS通常提供了多種類型的封鎖。一個事務對某個數據對象加鎖後究竟擁有什麼樣的控制是由封鎖的類型決定的。

封鎖的對象可以是邏輯單元,也可以是物理單元。邏輯單元: 屬性值、屬性值集合、元組、關系、索引項、整個索引、整個資料庫等;物理單元:頁(數據頁或索引頁)、塊等。

封鎖對象可以很大也可以很小,例如對整個資料庫加鎖、對某個屬性值加鎖。封鎖對象的大小稱為封鎖的粒度。封鎖的粒度越大,系統中能夠被封鎖的對象就越少,並發度也就越小,但系統開銷也越小;封鎖的粒度越小,並發度越高,但開銷也就越大。

參考資料來源:網路-封鎖

『肆』 Oracle資料庫鎖的常用類型有哪些

此文章主要是對Oracle資料庫鎖機制的詳細研究 首先我們要介紹的是Oracle資料庫鎖的類型 同時也闡述 在實際應用中我們經常會遇到的與鎖相關的異常情況 特別對經常遇到的由於等待鎖而使事務被掛起的問題進行了定位及解決 並對死鎖這一比較嚴重的現象 提出了相應的解決方法和具體的分析過程

資料庫是一個多用戶使用的共享資源 當多個用戶並發地存取數據時 在資料庫中就會產生多個事務同時存取同一數據的情況 若對並發操作不加控制就可能會讀取和存儲不正確的數據 破壞資料庫的一致性

加鎖是實現資料庫並發控制的一個非常重要的技術 當事務在對某個數據對象進行操作前 先向系統發出請求 對其加鎖 加鎖後事務就對該數據對象有了一定的控制 在該事務釋放鎖之前 其他的事務不能對此數據對象進行更新操作

在資料庫中有兩種基本的鎖類型 排它鎖(Exclusive Locks 即X鎖)和共享鎖(Share Locks 即S鎖) 當數據對象被加上排它鎖時 其他的事務不能對它讀取和修改 加了共享鎖的數據對象可以被其他事務讀取 但不能修改 資料庫利用這兩種基本的鎖類型來對Oracle資料庫的事務進行並發控制

在實際應用中經常會遇到的與鎖相關的異常情況 如由於等待鎖事務被掛起 死鎖等現象 如果不能及時地解決 將嚴重影響應用的正常執行 而目前對於該類問題的解決缺乏系統化研究和指導 本文在總結實際經驗的基礎上 提出了相應的解決方法和具體的分析過程

Oracle資料庫的鎖類型

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

DML鎖的目的在於保證並 *** 況下的數據完整性 本文主要討論DML鎖 在Oracle資料庫中 DML鎖主要包括TM鎖和TX鎖 其中TM鎖稱為表級鎖 TX鎖稱為事務鎖或行級鎖

當Oracle執行DML語句時 系統自動在所要操作的表上申請TM類型的鎖 當TM鎖獲得後 系統再自動申請TX類型的鎖 並將實際鎖定的數據行的鎖標志位進行置位 這樣在事務加鎖前檢查TX鎖相容性時就不用再逐行檢查鎖標志 而只需檢查TM鎖模式的相容性即可 大大提高了系統的效率

TM鎖包括了SS SX S X等多種模式 在Oracle資料庫中用 - 來表示 不同的SQL操作產生不同類型的TM鎖 如表 所示

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

當Oracle資料庫發生TX鎖等待時 如果不及時處理常常會引起Oracle資料庫掛起 或導致死鎖的發生 產生ORA 的錯誤 這些現象都會對實際應用產生極大的危害 如長時間未響應 大量事務失敗等

TX鎖等待的分析

在介紹了有關地Oracle資料庫鎖的種類後 下面討論如何有效地監控和解決鎖等待現象 及在產生死鎖時如何定位死鎖的原因

監控鎖的相關視圖 數據字典是Oracle資料庫的重要組成部分 用戶可以通過查詢數據字典視圖來獲得資料庫的信息 和鎖相關的數據字典視圖如表 所示

TX鎖等待的監控和解決在日常工作中 如果發現在執行某條SQL時資料庫長時間沒有響應 很可能是產生了TX鎖等待的現象 為解決這個問題 首先應該找出持鎖的事務 然後再進行相關的處理 如提交事務或強行中斷事務

死鎖的監控和解決在資料庫中 當兩個或多個會話請求同一個資源時會產生死鎖的現象 死鎖的常見類型是行級鎖死鎖和頁級鎖死鎖 Oracle資料庫中一般使用行級鎖 下面主要討論行級鎖的死鎖現象

當Oracle檢測到死鎖產生時 中斷並回滾死鎖相關語句的執行 報ORA 的錯誤並記錄在Oracle資料庫的日誌文件alertSID log中 同時在user_mp_dest下產生了一個跟蹤文件 詳細描述死鎖的相關信息

在日常工作中 如果發現在日誌文件中記錄了ora 的錯誤信息 則表明產生了死鎖 這時需要找到對應的跟蹤文件 根據跟蹤文件的信息定位產生的原因

如果查詢結果表明 死鎖是由於bitmap索引引起的 將IND_T_PRODUCT_HIS_STATE索引改為normal索引後 即可解決死鎖的問題

表 Oracle的TM鎖類型

鎖模式 鎖描述 解釋 SQL操作

none

NULL 空 Select

SS(Row S) 行級共享鎖 其他對象只能查詢這些數據行 Select for update Lock for update Lock row share

SX(Row X) 行級排它鎖 在提交前不允許做DML操作 Insert Update Delete Lock row share

S(Share) 共享鎖 Create index Lock share

SSX(S/Row X) 共享行級排它鎖 Lock share row exclusive

lishixin/Article/program/Oracle/201311/18509

『伍』 mysql資料庫的行級鎖有幾種

有兩種模式的行鎖:
1)共享鎖:允許一個事務去讀一行,阻止其他事務獲得相同數據集的排他鎖。
( Select * from table_name where ......lock in share mode)
2)排他鎖:允許獲得排他鎖的事務更新數據,阻止其他事務取得相同數據集的共享讀鎖和 排他寫鎖。(select * from table_name where.....for update)

『陸』 sql鎖表 分為幾種

1. 從資料庫系統的角度來看:分為獨占鎖(即排它鎖),共享鎖和更新鎖

MS-SQL Server 使用以下資源鎖模式。

鎖模式 描述

共享 (S) 用於不更改或不更新數據的操作(只讀操作),如 SELECT 語句。

更新 (U) 用於可更新的資源中。防止當多個會話在讀取、鎖定以及隨後可能進行的資源更新時發生常見形式的死鎖。

排它 (X) 用於數據修改操作,例如 INSERT、UPDATE 或 DELETE。確保不會同時同一資源進行多重更新。

意向鎖 用於建立鎖的層次結構。意向鎖的類型為:意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。

架構鎖 在執行依賴於表架構的操作時使用。架構鎖的類型為:架構修改 (Sch-M) 和架構穩定性 (Sch-S)。

大容量更新 (BU) 向表中大容量復制數據並指定了 TABLOCK 提示時使用。

◆共享鎖

共享 (S) 鎖允許並發事務讀取 (SELECT) 一個資源。資源上存在共享 (S) 鎖時,任何其它事務都不能修改數據。一旦已經讀取數據,便立即釋放資源上的共享 (S) 鎖,除非將事務隔離級別設置為可重復讀或更高級別,或者在事務生存周期內用鎖定提示保留共享 (S) 鎖。

◆更新鎖

更新 (U) 鎖可以防止通常形式的死鎖。一般更新模式由一個事務組成,此事務讀取記錄,獲取資源(頁或行)的共享 (S) 鎖,然後修改行,此操作要求鎖轉換為排它 (X) 鎖。如果兩個事務獲得了資源上的共享模式鎖,然後試圖同時更新數據,則一個事務嘗試將鎖轉換為排它 (X) 鎖。共享模式到排它鎖的轉換必須等待一段時間,因為一個事務的排它鎖與其它事務的共享模式鎖不兼容;發生鎖等待。第二個事務試圖獲取排它 (X) 鎖以進行更新。由於兩個事務都要轉換為排它 (X) 鎖,並且每個事務都等待另一個事務釋放共享模式鎖,因此發生死鎖。

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

◆排它鎖

排它 (X) 鎖可以防止並發事務對資源進行訪問。其它事務不能讀取或修改排它 (X) 鎖鎖定的數據。

『柒』 sql server中有幾種資源鎖,它們是系統自動分配的嗎

Microsoft SQL Server(以下簡稱SQL Server)作為一種中小型資料庫管理系統,已經得到了廣泛的應用,該系統更強調由系統來管理鎖。在用戶有SQL請求時,系統分析請求,自動在滿足鎖定條件和系統性能之間為資料庫加上適當的鎖,同時系統在運行期間常常自動進行優化處理,實行動態加鎖。 對於一般的用戶而言,通過系統的自動鎖定管理機制基本可以滿足使用要求,但如果對數據安全、資料庫完整性和一致性有特殊要求,就必須自己控制資料庫的鎖定和解鎖,這就需要了解SQL Server的鎖機制,掌握資料庫鎖定方法。 鎖的多粒度性以及鎖升級 資料庫中的鎖是指一種軟體機制,用來指示某個用戶(也即進程會話,下同)已經佔用了某種資源,從而防止其他用戶做出影響本用戶的數據修改或導致資料庫數據的非完整性和非一致性。這兒所謂資源,主要指用戶可以操作的數據行、索引以及數據表等。根據資源的不同,鎖有多粒度(multigranular)的概念,也就是指可以鎖定的資源的層次。SQL Server中能夠鎖定的資源粒度包括:資料庫、表、區域、頁面、鍵值(指帶有索引的行數據)、行標識符(RID,即表中的單行數據)。 採用多粒度鎖的重要用途是用來支持並發操作和保證數據的完整性。SQL Server根據用戶的請求,做出分析後自動給資料庫加上合適的鎖。假設某用戶只操作一個表中的部分行數據,系統可能會只添加幾個行鎖(RID)或頁面鎖,這樣可以盡可能多地支持多用戶的並發操作。但是,如果用戶事務中頻繁對某個表中的多條記錄操作,將導致對該表的許多記錄行都加上了行級鎖,資料庫系統中鎖的數目會急劇增加,這樣就加重了系統負荷,影響系統性能。因此,在資料庫系統中,一般都支持鎖升級(lock escalation)。所謂鎖升級是指調整鎖的粒度,將多個低粒度的鎖替換成少數的更高粒度的鎖,以此來降低系統負荷。在SQL Server中當一個事務中的鎖較多,達到鎖升級門限時,系統自動將行級鎖和頁面鎖升級為表級鎖。特別值得注意的是,在SQL Server中,鎖的升級門限以及鎖升級是由系統自動來確定的,不需要用戶設置。 SQL Server鎖類型 1. HOLDLOCK: 在該表上保持共享鎖,直到整個事務結束,而不是在語句執行完立即釋放所添加的鎖。 2. NOLOCK:不添加共享鎖和排它鎖,當這個選項生效後,可能讀到未提交讀的數據或「臟數據」,這個選項僅僅應用於SELECT語句。 3. PAGLOCK:指定添加頁鎖(否則通常可能添加表鎖)。 4. READCOMMITTED用與運行在提交讀隔離級別的事務相同的鎖語義執行掃描。默認情況下,SQL Server 2000 在此隔離級別上操作。。 5. READPAST: 跳過已經加鎖的數據行,這個選項將使事務讀取數據時跳過那些已經被其他事務鎖定的數據行,而不是阻塞直到其他事務釋放鎖,READPAST僅僅應用於READ COMMITTED隔離性級別下事務操作中的SELECT語句操作。 6. READUNCOMMITTED:等同於NOLOCK。 7. REPEATABLEREAD:設置事務為可重復讀隔離性級別。 8. ROWLOCK:使用行級鎖,而不使用粒度更粗的頁級鎖和表級鎖。 9. SERIALIZABLE:用與運行在可串列讀隔離級別的事務相同的鎖語義執行掃描。等同於 HOLDLOCK。 10. TABLOCK:指定使用表級鎖,而不是使用行級或頁面級的鎖,SQL Server在該語句執行完後釋放這個鎖,而如果同時指定了HOLDLOCK,該鎖一直保持到這個事務結束。 11. TABLOCKX:指定在表上使用排它鎖,這個鎖可以阻止其他事務讀或更新這個表的數據,直到這個語句或整個事務結束。 12. UPDLOCK :指定在讀表中數據時設置更新 鎖(update lock)而不是設置共享鎖,該鎖一直保持到這個語句或整個事務結束,使用UPDLOCK的作用是允許用戶先讀取數據(而且不阻塞其他用戶讀數據),並且保證在後來再更新數據時,這一段時間內這些數據沒有被其他用戶修改。

『捌』 關於MySQL中的表鎖和行鎖

mysql行鎖和表鎖

鎖是計算機協調多個進程或純線程並發訪問某一資源的機制。在資料庫中,除傳統的計算資源(CPU、RAM、I/O)的爭用以外,數據也是一種供許多用戶共享的資源。如何保證數據並發訪問的一致性、有效性是所在有資料庫必須解決的一個問題,鎖沖突也是影響資料庫並發訪問性能的一個重要因素。從這個角度來說,鎖對資料庫而言顯得尤其重要,也更加復雜。

概述

相對其他資料庫而言,MySQL的鎖機制比較簡單,其最顯著的特點是不同的存儲引擎支持不同的鎖機制。

MySQL大致可歸納為以下3種鎖:

  1. 表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,並發度最低。

  2. 行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,並發度也最高。

  3. 頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,並發度一般

    MySQL表級鎖的鎖模式(MyISAM)

    MySQL表級鎖有兩種模式:表共享鎖(Table Read Lock)和表獨占寫鎖(Table Write Lock)。

  1. 對MyISAM的讀操作,不會阻塞其他用戶對同一表請求,但會阻塞對同一表的寫請求;

  2. 對MyISAM的寫操作,則會阻塞其他用戶對同一表的讀和寫操作;

  3. MyISAM表的讀操作和寫操作之間,以及寫操作之間是串列的。

    當一個線程獲得對一個表的寫鎖後,只有持有鎖線程可以對表進行更新操作。其他線程的讀、寫操作都會等待,直到鎖被釋放為止。

    MySQL表級鎖的鎖模式

    MySQL的表鎖有兩種模式:表共享讀鎖(Table Read Lock)和表獨占寫鎖(Table Write Lock)。鎖模式的兼容如下表

    MySQL中的表鎖兼容性

    當前鎖模式/是否兼容/請求鎖模式

    讀鎖 是 是 否

    寫鎖 是 否 否

    可見,對MyISAM表的讀操作,不會阻塞其他用戶對同一表的讀請求,但會阻塞對同一表的寫請求;對MyISAM表的寫操作,則會阻塞其他用戶對同一表的讀和寫請求;MyISAM表的讀和寫操作之間,以及寫和寫操作之間是串列的!(當一線程獲得對一個表的寫鎖後,只有持有鎖的線程可以對表進行更新操作。其他線程的讀、寫操作都會等待,直到鎖被釋放為止。)

    如何加表鎖

    MyISAM在執行查詢語句(SELECT)前,會自動給涉及的所有表加讀鎖,在執行更新操作(UPDATE、DELETE、INSERT等)前,會自動給涉及的表加寫鎖,這個過程並不需要用戶干預,因此用戶一般不需要直接用LOCK TABLE命令給MyISAM表顯式加鎖。在本書的示例中,顯式加鎖基本上都是為了方便而已,並非必須如此。

    給MyISAM表顯示加鎖,一般是為了一定程度模擬事務操作,實現對某一時間點多個表的一致性讀取。

    要特別說明以下兩點內容。

  • 上面的例子在LOCK TABLES時加了『local』選項,其作用就是在滿足MyISAM表並發插入條件的情況下,允許其他用戶在表尾插入記錄

  • 在用LOCKTABLES給表顯式加表鎖是時,必須同時取得所有涉及表的鎖,並且MySQL支持鎖升級。也就是說,在執行LOCK TABLES後,只能訪問顯式加鎖的這些表,不能訪問未加鎖的表;同時,如果加的是讀鎖,那麼只能執行查詢操作,而不能執行更新操作。其實,在自動加鎖的情況下也基本如此,MySQL問題一次獲得SQL語句所需要的全部鎖。這也正是MyISAM表不會出現死鎖(Deadlock Free)的原因

  • 一個session使用LOCK TABLE 命令給表film_text加了讀鎖,這個session可以查詢鎖定表中的記錄,但更新或訪問其他表都會提示錯誤;同時,另外一個session可以查詢表中的記錄,但更新就會出現鎖等待。

    當使用LOCK TABLE時,不僅需要一次鎖定用到的所有表,而且,同一個表在SQL語句中出現多少次,就要通過與SQL語句中相同的別名鎖多少次,否則也會出錯!

    並發鎖

    在一定條件下,MyISAM也支持查詢和操作的並發進行。

    MyISAM存儲引擎有一個系統變數concurrent_insert,專門用以控制其並發插入的行為,其值分別可以為0、1或2。

  • 當concurrent_insert設置為0時,不允許並發插入。

  • 當concurrent_insert設置為1時,如果MyISAM允許在一個讀表的同時,另一個進程從表尾插入記錄。這也是MySQL的默認設置。

  • 當concurrent_insert設置為2時,無論MyISAM表中有沒有空洞,都允許在表尾插入記錄,都允許在表尾並發插入記錄。

  • 可以利用MyISAM存儲引擎的並發插入特性,來解決應用中對同一表查詢和插入鎖爭用。例如,將concurrent_insert系統變數為2,總是允許並發插入;同時,通過定期在系統空閑時段執行OPTIONMIZE TABLE語句來整理空間碎片,收到因刪除記錄而產生的中間空洞。

    MyISAM的鎖調度

    前面講過,MyISAM存儲引擎的讀和寫鎖是互斥,讀操作是串列的。那麼,一個進程請求某個MyISAM表的讀鎖,同時另一個進程也請求同一表的寫鎖,MySQL如何處理呢?答案是寫進程先獲得鎖。不僅如此,即使讀進程先請求先到鎖等待隊列,寫請求後到,寫鎖也會插到讀請求之前!這是因為MySQL認為寫請求一般比讀請求重要。這也正是MyISAM表不太適合於有大量更新操作和查詢操作應用的原因,因為,大量的更新操作會造成查詢操作很難獲得讀鎖,從而可能永遠阻塞。這種情況有時可能會變得非常糟糕!幸好我們可以通過一些設置來調節MyISAM的調度行為。

  • 通過指定啟動參數low-priority-updates,使MyISAM引擎默認給予讀請求以優先的權利。

  • 通過執行命令SET LOW_PRIORITY_UPDATES=1,使該連接發出的更新請求優先順序降低。

  • 通過指定INSERT、UPDATE、DELETE語句的LOW_PRIORITY屬性,降低該語句的優先順序。

  • 雖然上面3種方法都是要麼更新優先,要麼查詢優先的方法,但還是可以用其來解決查詢相對重要的應用(如用戶登錄系統)中,讀鎖等待嚴重的問題。

    另外,MySQL也提供了一種折中的辦法來調節讀寫沖突,即給系統參數max_write_lock_count設置一個合適的值,當一個表的讀鎖達到這個值後,MySQL變暫時將寫請求的優先順序降低,給讀進程一定獲得鎖的機會。

    上面已經討論了寫優先調度機制和解決辦法。這里還要強調一點:一些需要長時間運行的查詢操作,也會使寫進程「餓死」!因此,應用中應盡量避免出現長時間運行的查詢操作,不要總想用一條SELECT語句來解決問題。因為這種看似巧妙的SQL語句,往往比較復雜,執行時間較長,在可能的情況下可以通過使用中間表等措施對SQL語句做一定的「分解」,使每一步查詢都能在較短時間完成,從而減少鎖沖突。如果復雜查詢不可避免,應盡量安排在資料庫空閑時段執行,比如一些定期統計可以安排在夜間執行。

    InnoDB鎖問題

    InnoDB與MyISAM的最大不同有兩點:一是支持事務(TRANSACTION);二是採用了行級鎖。

    行級鎖和表級鎖本來就有許多不同之處,另外,事務的引入也帶來了一些新問題。

    1.事務(Transaction)及其ACID屬性

    事務是由一組SQL語句組成的邏輯處理單元,事務具有4屬性,通常稱為事務的ACID屬性。

  • 原性性(Actomicity):事務是一個原子操作單元,其對數據的修改,要麼全都執行,要麼全都不執行。

  • 一致性(Consistent):在事務開始和完成時,數據都必須保持一致狀態。這意味著所有相關的數據規則都必須應用於事務的修改,以操持完整性;事務結束時,所有的內部數據結構(如B樹索引或雙向鏈表)也都必須是正確的。

  • 隔離性(Isolation):資料庫系統提供一定的隔離機制,保證事務在不受外部並發操作影響的「獨立」環境執行。這意味著事務處理過程中的中間狀態對外部是不可見的,反之亦然。

  • 持久性(Durable):事務完成之後,它對於數據的修改是永久性的,即使出現系統故障也能夠保持。

  • 2.並發事務帶來的問題

    相對於串列處理來說,並發事務處理能大大增加資料庫資源的利用率,提高資料庫系統的事務吞吐量,從而可以支持可以支持更多的用戶。但並發事務處理也會帶來一些問題,主要包括以下幾種情況。

  • 更新丟失(Lost Update):當兩個或多個事務選擇同一行,然後基於最初選定的值更新該行時,由於每個事務都不知道其他事務的存在,就會發生丟失更新問題——最後的更新覆蓋了其他事務所做的更新。例如,兩個編輯人員製作了同一文檔的電子副本。每個編輯人員獨立地更改其副本,然後保存更改後的副本,這樣就覆蓋了原始文檔。最後保存其更改保存其更改副本的編輯人員覆蓋另一個編輯人員所做的修改。如果在一個編輯人員完成並提交事務之前,另一個編輯人員不能訪問同一文件,則可避免此問題

  • 臟讀(Dirty Reads):一個事務正在對一條記錄做修改,在這個事務並提交前,這條記錄的數據就處於不一致狀態;這時,另一個事務也來讀取同一條記錄,如果不加控制,第二個事務讀取了這些「臟」的數據,並據此做進一步的處理,就會產生未提交的數據依賴關系。這種現象被形象地叫做「臟讀」。

  • 不可重復讀(Non-Repeatable Reads):一個事務在讀取某些數據已經發生了改變、或某些記錄已經被刪除了!這種現象叫做「不可重復讀」。

  • 幻讀(Phantom Reads):一個事務按相同的查詢條件重新讀取以前檢索過的數據,卻發現其他事務插入了滿足其查詢條件的新數據,這種現象就稱為「幻讀」。

  • 3.事務隔離級別

    在並發事務處理帶來的問題中,「更新丟失」通常應該是完全避免的。但防止更新丟失,並不能單靠資料庫事務控制器來解決,需要應用程序對要更新的數據加必要的鎖來解決,因此,防止更新丟失應該是應用的責任。

    「臟讀」、「不可重復讀」和「幻讀」,其實都是資料庫讀一致性問題,必須由資料庫提供一定的事務隔離機制來解決。資料庫實現事務隔離的方式,基本可以分為以下兩種。

    一種是在讀取數據前,對其加鎖,阻止其他事務對數據進行修改。

    另一種是不用加任何鎖,通過一定機制生成一個數據請求時間點的一致性數據快照(Snapshot),並用這個快照來提供一定級別(語句級或事務級)的一致性讀取。從用戶的角度,好像是資料庫可以提供同一數據的多個版本,因此,這種技術叫做數據多版本並發控制(MultiVersion Concurrency Control,簡稱MVCC或MCC),也經常稱為多版本資料庫。

    資料庫的事務隔離級別越嚴格,並發副作用越小,但付出的代價也就越大,因為事務隔離實質上就是使事務在一定程度上「串列化」進行,這顯然與「並發」是矛盾的,同時,不同的應用對讀一致性和事務隔離程度的要求也是不同的,比如許多應用對「不可重復讀」和「幻讀」並不敏感,可能更關心數據並發訪問的能力。

    為了解決「隔離」與「並發」的矛盾,ISO/ANSI SQL92定義了4個事務隔離級別,每個級別的隔離程度不同,允許出現的副作用也不同,應用可以根據自己業務邏輯要求,通過選擇不同的隔離級別來平衡"隔離"與"並發"的矛盾

    事務4種隔離級別比較

    隔離級別/讀數據一致性及允許的並發副作用 讀數據一致性 臟讀 不可重復讀 幻讀

    未提交讀(Read uncommitted)

  • 最低級別,只能保證不讀取物理上損壞的數據 是 是 是

  • 已提交度(Read committed) 語句級 否 是 是

    可重復讀(Repeatable read) 事務級 否 否 是

    可序列化(Serializable) 最高級別,事務級 否 否 否

    最後要說明的是:各具體資料庫並不一定完全實現了上述4個隔離級別,例如,Oracle只提供Read committed和Serializable兩個標准級別,另外還自己定義的Read only隔離級別:SQL Server除支持上述ISO/ANSI SQL92定義的4個級別外,還支持一個叫做"快照"的隔離級別,但嚴格來說它是一個用MVCC實現的Serializable隔離級別。MySQL支持全部4個隔離級別,但在具體實現時,有一些特點,比如在一些隔離級下是採用MVCC一致性讀,但某些情況又不是。

    獲取InonoD行鎖爭用情況

    可以通過檢查InnoDB_row_lock狀態變數來分析系統上的行鎖的爭奪情況:

    如果發現爭用比較嚴重,如Innodb_row_lock_waits和Innodb_row_lock_time_avg的值比較高,還可以通過設置InnoDB Monitors來進一步觀察發生鎖沖突的表、數據行等,並分析鎖爭用的原因。

    InnoDB的行鎖模式及加鎖方法

    InnoDB實現了以下兩種類型的行鎖。

  • 共享鎖(s):允許一個事務去讀一行,阻止其他事務獲得相同數據集的排他鎖。

  • 排他鎖(X):允許獲取排他鎖的事務更新數據,阻止其他事務取得相同的數據集共享讀鎖和排他寫鎖。

  • 另外,為了允許行鎖和表鎖共存,實現多粒度鎖機制,InnoDB還有兩種內部使用的意向鎖(Intention Locks),這兩種意向鎖都是表鎖。

    意向共享鎖(IS):事務打算給數據行共享鎖,事務在給一個數據行加共享鎖前必須先取得該表的IS鎖。

    意向排他鎖(IX):事務打算給數據行加排他鎖,事務在給一個數據行加排他鎖前必須先取得該表的IX鎖。

    InnoDB行鎖模式兼容性列表

    如果一個事務請求的鎖模式與當前的鎖兼容,InnoDB就請求的鎖授予該事務;反之,如果兩者兩者不兼容,該事務就要等待鎖釋放。

    意向鎖是InnoDB自動加的,不需用戶干預。對於UPDATE、DELETE和INSERT語句,InnoDB會自動給涉及及數據集加排他鎖(X);對於普通SELECT語句,InnoDB會自動給涉及數據集加排他鎖(X);對於普通SELECT語句,InnoDB不會任何鎖;事務可以通過以下語句顯示給記錄集加共享鎖或排鎖。

    共享鎖(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE

    排他鎖(X):SELECT * FROM table_name WHERE ...FOR UPDATE

    用SELECT .. IN SHARE MODE獲得共享鎖,主要用在需要數據依存關系時確認某行記錄是否存在,並確保沒有人對這個記錄進行UPDATE或者DELETE操作。但是如果當前事務也需要對該記錄進行更新操作,則很有可能造成死鎖,對於鎖定行記錄後需要進行更新操作的應用,應該使用SELECT ... FOR UPDATE方式獲取排他鎖。

    InnoDB行鎖實現方式

    InnoDB行鎖是通過索引上的索引項來實現的,這一點MySQL與Oracle不同,後者是通過在數據中對相應數據行加鎖來實現的。InnoDB這種行鎖實現特點意味者:只有通過索引條件檢索數據,InnoDB才會使用行級鎖,否則,InnoDB將使用表鎖!

    在實際應用中,要特別注意InnoDB行鎖的這一特性,不然的話,可能導致大量的鎖沖突,從而影響並發性能。

    什麼時候使用表鎖

    對於InnoDB表,在絕大部分情況下都應該使用行級鎖,因為事務和行鎖往往是我們之所以選擇InnoDB表的理由。但在個另特殊事務中,也可以考慮使用表級鎖。

  • 第一種情況是:事務需要更新大部分或全部數據,表又比較大,如果使用默認的行鎖,不僅這個事務執行效率低,而且可能造成其他事務長時間鎖等待和鎖沖突,這種情況下可以考慮使用表鎖來提高該事務的執行速度。

  • 第二種情況是:事務涉及多個表,比較復雜,很可能引起死鎖,造成大量事務回滾。這種情況也可以考慮一次性鎖定事務涉及的表,從而避免死鎖、減少資料庫因事務回滾帶來的開銷。

  • 當然,應用中這兩種事務不能太多,否則,就應該考慮使用MyISAM表。

    在InnoDB下 ,使用表鎖要注意以下兩點。

    (1)使用LOCK TALBES雖然可以給InnoDB加表級鎖,但必須說明的是,表鎖不是由InnoDB存儲引擎層管理的,而是由其上一層MySQL Server負責的,僅當autocommit=0、innodb_table_lock=1(默認設置)時,InnoDB層才能知道MySQL加的表鎖,MySQL Server才能感知InnoDB加的行鎖,這種情況下,InnoDB才能自動識別涉及表級鎖的死鎖;否則,InnoDB將無法自動檢測並處理這種死鎖。

    (2)在用LOCAK TABLES對InnoDB鎖時要注意,要將AUTOCOMMIT設為0,否則MySQL不會給表加鎖;事務結束前,不要用UNLOCAK TABLES釋放表鎖,因為UNLOCK TABLES會隱含地提交事務;COMMIT或ROLLBACK產不能釋放用LOCAK TABLES加的表級鎖,必須用UNLOCK TABLES釋放表鎖,正確的方式見如下語句。

    關於死鎖

    MyISAM表鎖是deadlock free的,這是因為MyISAM總是一次性獲得所需的全部鎖,要麼全部滿足,要麼等待,因此不會出現死鎖。但是在InnoDB中,除單個SQL組成的事務外,鎖是逐步獲得的,這就決定了InnoDB發生死鎖是可能的。

    發生死鎖後,InnoDB一般都能自動檢測到,並使一個事務釋放鎖並退回,另一個事務獲得鎖,繼續完成事務。但在涉及外部鎖,或涉及鎖的情況下,InnoDB並不能完全自動檢測到死鎖,這需要通過設置鎖等待超時參數innodb_lock_wait_timeout來解決。需要說明的是,這個參數並不是只用來解決死鎖問題,在並發訪問比較高的情況下,如果大量事務因無法立即獲取所需的鎖而掛起,會佔用大量計算機資源,造成嚴重性能問題,甚至拖垮資料庫。我們通過設置合適的鎖等待超時閾值,可以避免這種情況發生。

    通常來說,死鎖都是應用設計的問題,通過調整業務流程、資料庫對象設計、事務大小、以及訪問資料庫的SQL語句,絕大部分都可以避免。下面就通過實例來介紹幾種死鎖的常用方法。

    (1)在應用中,如果不同的程序會並發存取多個表,應盡量約定以相同的順序為訪問表,這樣可以大大降低產生死鎖的機會。如果兩個session訪問兩個表的順序不同,發生死鎖的機會就非常高!但如果以相同的順序來訪問,死鎖就可能避免。

    (2)在程序以批量方式處理數據的時候,如果事先對數據排序,保證每個線程按固定的順序來處理記錄,也可以大大降低死鎖的可能。

    (3)在事務中,如果要更新記錄,應該直接申請足夠級別的鎖,即排他鎖,而不應該先申請共享鎖,更新時再申請排他鎖,甚至死鎖。

    (4)在REPEATEABLE-READ隔離級別下,如果兩個線程同時對相同條件記錄用SELECT...ROR UPDATE加排他鎖,在沒有符合該記錄情況下,兩個線程都會加鎖成功。程序發現記錄尚不存在,就試圖插入一條新記錄,如果兩個線程都這么做,就會出現死鎖。這種情況下,將隔離級別改成READ COMMITTED,就可以避免問題。

    (5)當隔離級別為READ COMMITED時,如果兩個線程都先執行SELECT...FOR UPDATE,判斷是否存在符合條件的記錄,如果沒有,就插入記錄。此時,只有一個線程能插入成功,另一個線程會出現鎖等待,當第1個線程提交後,第2個線程會因主鍵重出錯,但雖然這個線程出錯了,卻會獲得一個排他鎖!這時如果有第3個線程又來申請排他鎖,也會出現死鎖。對於這種情況,可以直接做插入操作,然後再捕獲主鍵重異常,或者在遇到主鍵重錯誤時,總是執行ROLLBACK釋放獲得的排他鎖。

    盡管通過上面的設計和優化等措施,可以大減少死鎖,但死鎖很難完全避免。因此,在程序設計中總是捕獲並處理死鎖異常是一個很好的編程習慣。

    如果出現死鎖,可以用SHOW INNODB STATUS命令來確定最後一個死鎖產生的原因和改進措施。

    總結

    對於MyISAM的表鎖,主要有以下幾點

    (1)共享讀鎖(S)之間是兼容的,但共享讀鎖(S)和排他寫鎖(X)之間,以及排他寫鎖之間(X)是互斥的,也就是說讀和寫是串列的。

    (2)在一定條件下,MyISAM允許查詢和插入並發執行,我們可以利用這一點來解決應用中對同一表和插入的鎖爭用問題。

    (3)MyISAM默認的鎖調度機制是寫優先,這並不一定適合所有應用,用戶可以通過設置LOW_PRIPORITY_UPDATES參數,或在INSERT、UPDATE、DELETE語句中指定LOW_PRIORITY選項來調節讀寫鎖的爭用。

    (4)由於表鎖的鎖定粒度大,讀寫之間又是串列的,因此,如果更新操作較多,MyISAM表可能會出現嚴重的鎖等待,可以考慮採用InnoDB表來減少鎖沖突。

    對於InnoDB表,主要有以下幾點

    (1)InnoDB的行銷是基於索引實現的,如果不通過索引訪問數據,InnoDB會使用表鎖。

    (2)InnoDB間隙鎖機制,以及InnoDB使用間隙鎖的原因。

    (3)在不同的隔離級別下,InnoDB的鎖機制和一致性讀策略不同。

    (4)MySQL的恢復和復制對InnoDB鎖機制和一致性讀策略也有較大影響。

    (5)鎖沖突甚至死鎖很難完全避免。

    在了解InnoDB的鎖特性後,用戶可以通過設計和SQL調整等措施減少鎖沖突和死鎖,包括:

  • 盡量使用較低的隔離級別

  • 精心設計索引,並盡量使用索引訪問數據,使加鎖更精確,從而減少鎖沖突的機會。

  • 選擇合理的事務大小,小事務發生鎖沖突的幾率也更小。

  • 給記錄集顯示加鎖時,最好一次性請求足夠級別的鎖。比如要修改數據的話,最好直接申請排他鎖,而不是先申請共享鎖,修改時再請求排他鎖,這樣容易產生死鎖。

  • 不同的程序訪問一組表時,應盡量約定以相同的順序訪問各表,對一個表而言,盡可能以固定的順序存取表中的行。這樣可以大減少死鎖的機會。

  • 盡量用相等條件訪問數據,這樣可以避免間隙鎖對並發插入的影響。

  • 不要申請超過實際需要的鎖級別;除非必須,查詢時不要顯示加鎖。

  • 對於一些特定的事務,可以使用表鎖來提高處理速度或減少死鎖的可能

『玖』 什麼是封鎖基本的封鎖類型有幾種試述它們的含義

封鎖是指事務T在對某個數據對象(例如表、記錄等)操作之前,先向系統發出請求,對其加鎖。加鎖後事務T就對該數據對象有了一定的控制,在事務T釋放它的鎖之前,其它的事務不能更新此數據對象。

基本類型:排它鎖(記為X鎖)、共享鎖(記為S鎖)

1、排它鎖又稱為寫鎖。若事務T 對數據對象A 加上X 鎖,則只允許T 讀取和修改A , 其它任何事務都不能再對A 加任何類型的鎖,直到T 釋放A 上的鎖。

2、共享鎖又稱為讀鎖。若事務T 對數據對象A 加上S 鎖,則其它事務只能再對A 加S 鎖,而不能加X 鎖,直到T 釋放A 上的S 鎖。

(9)資料庫系統為其分配的鎖類型為擴展閱讀:

一、封鎖單元,封鎖的對象可以是邏輯單元,也可以是物理單元。

1、邏輯單元: 屬性值、屬性值集合、元組、關系、索引項、整個索引、整個資料庫等;

2、物理單元:頁(數據頁或索引頁)、塊等。

二、封鎖粒度,封鎖對象可以很大也可以很小,例如對整個資料庫加鎖、對某個屬性值加鎖。封鎖對象的大小稱為封鎖的粒度。封鎖的粒度越大,系統中能夠被封鎖的對象就越少,並發度也就越小,但系統開銷也越小;封鎖的粒度越小,並發度越高,但開銷也就越大。

三、粒度選擇,選擇封鎖粒度時必須同時考慮開銷和並發度兩個因素,進行權衡,以求得最優的效果。