資料庫事務特性與隔離級別

2021-09-24 14:13:00 字數 4740 閱讀 3981

原子性(atomicity):

乙個事務包含多個操作,這些操作要麼全部執行,要麼全都不執行。實現事務的原子性,要支援回滾操作,在某個操作失敗後,回滾到事務執行之前的狀態。

一致性(consistency):

事務的一致性指的是在乙個事務執行之前和執行之後資料庫都必須處於一致性狀態(正確的狀態)。這種特性稱為事務的一致性。假如資料庫的狀態滿足所有的完整性約束,就說該資料庫是一致的。

什麼叫正確的狀態呢?就是當前的資料滿足預定的約束條件就叫做正確的狀態。實際上它依賴於應用層來實現,也就是依賴於開發者來實現。資料庫是利用aid(特別是a)來支援一致性的,所以說一致性與原子性緊密相關。

事務可以不同程度的一致性:

強一致性:讀操作可以立即讀到提交的更新操作。

弱一致性:提交的更新操作,不一定立即會被讀操作讀到,此種情況會存在乙個不一致視窗,指的是讀操作可以讀到最新值的一段時間。

最終一致性:是弱一致性的特例。事務更新乙份資料,最終一致性保證在沒有其他事務更新同樣的值的話,最終所有的事務都會讀到之前事務更新的最新值。如果沒有錯誤發生,不一致視窗的大小依賴於:通訊延遲,系統負載等。

單調一致性:如果乙個程序已經讀到乙個值,那麼後續不會讀到更早的值。

會話一致性:保證客戶端和伺服器互動的會話過程中,讀操作可以讀到更新操作後的最新值。

隔離性(isolation):

由併發事務所作的修改必須與任何其它併發事務所作的修改隔離。事務檢視資料時資料所處的狀態,到底是另乙個事務執行之前的狀態還是中間某個狀態,相互之間存在什麼影響,是可以通過隔離級別的設定來控制的。

事務可以不同程度的隔離性(隔離級別):

讀未提交、讀已提交、可重複讀、可序列化。

下文會有事務隔離級別詳細說明,這裡不做過多的解釋。

永續性(durability):

事務結束後,事務處理的結果必須能夠得到固化,不可回滾,即寫入資料庫檔案中即使機器宕機資料也不會丟失,它對於系統的影響是永久性的。

髒讀:乙個事務讀取到其他事務未提交的資料。

如,事務a修改了乙個資料,但未提交,事務b讀到了事務a未提交的更新結果,如果事務a提交失敗,事務b讀到的就是髒資料。

不可重複讀:在同乙個事務中,對於同乙份資料讀取到的結果不一致。

如,事務a中執行了兩個查詢,但在事務a的執行過程中,事務b對要查詢的資料進行了修改並提交,此時會造成事務a前面的查詢是事務b修改之前的資料,事務a後面的查詢是事務b修改之後的資料。

不可重複讀出現的原因就是事務併發修改記錄,要避免這種情況,最簡單的方法就是對要修改的資料加行鎖,這會導致鎖競爭加劇,影響效能。另一種方法是通過mvcc可以在無鎖的情況下,避免不可重複讀。

幻讀:在同乙個事務中,同乙個查詢多次返回的結果不一致。

和不可重複度類似,區別在於幻讀的關注的是整個表(增刪資料),不可重複度關注的是具體的資料(修改資料)。

幻讀是由於併發事務增刪資料導致的,這個不能像不可重複讀通過加行鎖解決,因為對於新增的資料根本無法加行鎖。需要將事務序列化,或鎖表,才能避免幻讀。

(1)read uncommitted 讀未提交

最低的隔離級別,乙個事務可以讀到另乙個事務未提交的結果,該級別下所有的併發事務問題都會發生。

(2)read committed 讀已提交

任何事務只可以讀取其他事務已提交的資料,可以解決髒讀問題。

(3)repeatable read 可重複讀

在乙個事務中,對於同乙份資料的讀取結果總是相同的,無論是否有其他事務對這份資料進行操作,以及這個事務是否提交。該級別可以解決髒讀、不可重複讀,但存在可能將未提交的記錄查詢出來,而出現幻讀問題。

(4)serializable 可序列化

事務序列化執行(強制排序後按順序執行),隔離級別最高,該級別下所有的併發事務問題都不會發生,但會導致大量超時現象和鎖競爭。

事務隔離級別

髒讀不可重複讀

幻讀讀未提交(read uncommitted)是是

是讀已提交(read committed)否是

是可重複讀(repeatable read)否否

是可序列化(serializable)否否

否mysql innodb支援事務四大隔離級別(mysql其他儲存引擎不支援事務),預設隔離級別是repeatable read。

查詢和設定事務隔離級別:

select @@tx_isolation;--檢視當前會話隔離級別

select @@global.tx_isolation;--檢視系統當前隔離級別

set session transaction isolatin level repeatable read;--設定當前會話隔離級別

set global transaction isolation level repeatable read;--設定系統當前隔離級別

oracle資料庫支援read committed和serializable,預設隔離級別是read committed。

查詢和設定事務隔離級別:

-為了查詢事務隔離級別,首先建立乙個事務

declare trans_id varchar2(100);

begin trans_id := dbms_transaction.local_transaction_id( true );end;

--檢視事務隔離級別

select s.sid, s.serial#,case bitand(t.flag, power(2, 28)) when 0 then 'read committed' else 'serializable' end isolation_level

from v$transaction t join v$session s on t.addr = s.taddr and s.sid = sys_context('userenv', 'sid');

set transaction isolation level read committed;--設定系統當前隔離級別

set transaction isolation level serializable;--設定系統當前隔離級別

alter session set transaction isolation level read committed;--設定當前會話隔離級別

alter session set transaction isolation serializable;--設定當前會話隔離級別

--設定oracle事務是否唯讀(與本文無關,記在這裡為了作者自己看)

set transaction read only;--設定事務為唯讀,read only是oracle自己的事務隔離級別

set transaction read write;--設定事務為讀寫

鎖是計算機協調多個程序或純執行緒併發訪問某一資源的機制。

資料庫鎖分為兩類,乙個是悲觀鎖,乙個是樂觀鎖,悲觀鎖一般就是我們通常說的資料庫鎖機制,樂觀鎖一般是指使用者自己實現的一種鎖機制,比如hibernate實現的樂觀鎖甚至程式語言也有樂觀鎖的思想的應用。

悲觀鎖:對於資料被外界修改持悲觀態度,認為資料隨時會修改,所以整個資料處理中需要將資料加鎖。悲觀鎖一般都是依靠關聯式資料庫提供的鎖機制,事實上關聯式資料庫中的行鎖,表鎖不論是讀寫鎖都是悲觀鎖。

樂觀鎖:對於資料被外界修改持樂觀態度,認為每次自己運算元據的時候沒有人回來修改它,所以不去加鎖,但是在更新的時候會去判斷在此期間資料有沒有被修改,需要使用者自己去實現。既然都有資料庫提供的悲觀鎖可以方便使用為什麼要使用樂觀鎖呢?對於讀操作遠多於寫操作的時候,大多數都是讀取,這時候乙個更新操作加鎖會阻塞所有讀取,降低了吞吐量。最後還要釋放鎖,鎖是需要一些開銷的,我們只要想辦法解決極少量的更新操作的同步問題。換句話說,如果是讀寫比例差距不是非常大或者你的系統沒有響應不及時,吞吐量瓶頸問題,那就不要去使用樂觀鎖,它增加了複雜度,也帶來了額外的風險。

切記!每個資料庫對鎖的設計和實現各不相同,mysql鎖請參考:,oracle請參考,以下只針對以下共性和概念進行簡單描述。

悲觀鎖按照使用性質劃分:

又稱讀鎖、s鎖,當乙個事務為某個物件新增共享鎖後,其他事務只能對該物件加共享鎖,多個事務可以同時讀,但不能有寫操作,直到該物件釋放所有共享鎖。

又稱寫鎖,x鎖,但乙個事務為某個物件新增排它鎖後,其他事務不能對該物件加任何鎖,只有當前事務可以讀寫該物件,直到當前事務釋放該物件的排它鎖。

又稱u鎖,用來預定要對此物件施加排它鎖,它允許其他事務讀,但不允許再施加更新鎖或排它鎖,當被讀取的物件將要被更新時,則公升級為排它鎖。

主要是用來防止死鎖的。因為使用共享鎖時,修改資料的操作分為兩步,首先獲得乙個共享鎖,讀取資料,然後將共享鎖公升級為排它鎖,然後再執行修改操作。這樣如果同時有兩個或多個事務同時對乙個物件申請了共享鎖,在修改資料的時候,這些事務都要將共享鎖公升級為排它鎖。這些事務都不會釋放共享鎖而是一直等待對方釋放,這樣就造成了死鎖。如果乙個資料在修改前直接申請更新鎖,在資料修改的時候再公升級為排它鎖,就可以避免死鎖。

悲觀鎖按照作用範圍(鎖的物件)劃分:

鎖的作用範圍是行級別,資料庫能夠確定那些行需要鎖的情況下使用行鎖,如果不知道會影響哪些行的時候就會使用表鎖。

如,乙個使用者表user,有主鍵id和使用者生日birthday當你使用update … where id=?這樣的語句資料庫明確知道會影響哪一行,它就會使用行鎖,當你使用update … where birthday=?這樣的的語句的時候因為事先不知道會影響哪些行就可能會使用表鎖。

鎖的作用範圍是整張表。

資料庫事務特性以及隔離級別

資料庫如果支援事務的操作,那麼就具備以下四個特性 原子性 atomicity 事務是資料庫的邏輯工作單位,事務中包括的諸操作要麼全做,要麼全不做。一致性 consistency 事務執行的結果必須是使資料庫從乙個一致性狀態變到另乙個一致性狀態。一致性與原子性是密切相關的。隔離性 isolation ...

資料庫事務特性及隔離級別

1.原子性 atomicity 2.一致性 consistency 3.隔離性 durability 4.永續性在高併發情況下,要完成保證事務acid特性是十分困難的,除非把所有的事務序列化執行,但是因此造成的影響將是系統效能大大降低。在實際開發中很多業務對事務的要求是不一樣的,因此資料庫設計了四種...

資料庫事務特性和隔離級別

一 事務的基本要素 acid 1 原子性 atomicity 事務開始後所有操作,要麼全部做完,要麼全部不做,不可能停滯在中間環節。事務執行過程中出錯,會回滾到事務開始前的狀態,所有的操作就像沒有發生一樣。也就是說事務是乙個不可分割的整體,就像化學中學過的原子,是物質構成的基本單位。2 一致性 co...