資料庫事務深入分析

2021-07-22 07:48:16 字數 3292 閱讀 4240

1、原子性(atomic)2、一致性(consistent)

一致性要求事務執行完成後,將資料庫從乙個狀態轉變為另乙個狀態,他是一種以一致性規則為基礎的邏輯屬性,例如在轉賬操作中,個賬戶金額必須平衡;

3、隔離性(insulation)

乙個事務的執行不能被其他事務所干擾。即乙個事務內部的操作及使用的資料對併發的其他事務是隔離的,併發執行的各個事務之間不能相互干擾。它要求即使有多個事務併發執行,看上去每個成功事務按穿行排程執行一樣,即在乙個事務沒有結束之前,另外的事務操作不能開始。由於序列排程的效能問題,我們需要進行交錯操作的排程,使其效果與序列排程一致,實現機制通過對事務的資料訪問物件加適當的鎖,從而排斥其他事務對同意資料庫物件的併發操作;

4、永續性(duration)

事務完成之後,他對系統的影響是永久性的,系統發生故障之後也不能改變事務的永續性;

i、資料庫多事務併發影響及例項

1、出現髒讀

當事務a訪問資料庫,並且對資料進行修改 而這種修改還沒有提交到資料庫中,這時,事務b訪問資料庫,可以看到事務a修改的結果;若此時事務a進行資料回滾,事務b再次查詢,得到的結果是事務a回滾之後的資料

以取款事務和櫃檯轉賬事務為例:

取款事務包含以下步驟:

(1)某銀行客戶在銀行前台請求取款100元,出納員先查詢賬戶資訊,得知存款餘額為1000元。

(2)出納員判斷出存款額超過了取款額,就支付給客戶100元,並將賬戶上的存款餘額改為900元。

支票轉賬事務包含以下步驟:

(1)某出納員處理一轉帳支票,該支票向一帳戶匯入100元。出納員先查詢賬戶資訊,得知存款餘額為900元。

(2)出納員將存款餘額改為1000元。

取款事務在t5時刻把存款餘額改為900元,轉賬事務在t6時刻查詢賬戶的存款餘額為900元,取款事務在t7時刻被撤銷,支票轉賬事務在t8時刻把存款餘額改為1000元。

由於支票轉賬事務查詢到了取款事務未提交的更新資料,並且在這個查詢結果的基礎上進行更新操作,如果取款事務最後被撤銷,會導致銀行客戶損失100元。

2、*不可重複讀*

當事務a訪問資料庫,並且對資料進行了修改,緊當事務a的修改已經提交到資料庫後,事務b訪問資料庫,才可以看到事務a修改的結果;

取款事務在t5時刻根據在t3時刻的查詢結果,把存款餘額改為1000-100元,在t7時刻提交事務。轉賬事務在t8時刻根據在t6時刻的查詢結果,把存款餘額改為1000+100元。由於支票轉賬事務覆蓋了取款事務對存款餘額所做的更新,導致銀行最後損失100元。

這也稱為第二類丟失更新,即乙個事務覆蓋另乙個事務已提交的更新資料

這種情況是如何出現的?

我們首先就需要了解資料庫的鎖機制

共享鎖【s鎖】

又稱讀鎖,若事務t對資料物件a加上s鎖,則事務t可以讀a但不能修改a,其他事務只能再對a加s鎖,而不能加x鎖,直到t釋放a上的s鎖。這保證了其他事務可以讀a,但在t釋放a上的s鎖之前不能對a做任何修改。

排他鎖【x鎖】

又稱寫鎖。若事務t對資料物件a加上x鎖,事務t可以讀a也可以修改a,其他事務不能再對a加任何鎖,直到t釋放a上的鎖。這保證了其他事務在t釋放a上的鎖之前不能再讀取和修改a。

**封鎖協議:

一級封鎖協議:事務t在修改資料r之前必須先對其加x鎖,直到事務結束才釋放。事務結束包括正常結束(commit)和非正常結束(rollback)。 一級封鎖協議可以防止丟失修改,並保證事務t是可恢復的。使用一級封鎖協議可以解決丟失修改問題。在一級封鎖協議中,如果僅僅是讀資料不對其進行修改,是不需要加鎖的,它不能保證不可重複讀。

二級封鎖協議:一級封鎖協議加上事務t在讀取資料r之前必須先對其加s鎖,讀完後方可釋放s鎖。 二級封鎖協議除防止了丟失修改,還可以進一步防止讀「髒」資料。但在二級封鎖協議中,由於讀完資料後即可釋放s鎖,所以它不能保證可重複讀。

**封鎖協議 :一級封鎖協議加上事務t在讀取資料r之前必須先對其加s鎖,直到事務結束才釋放。 **封鎖協議除防止了丟失修改和不讀「髒」資料外,還進一步防止了不可重複讀。

當我們將資料庫級別設定為read committed時使用了一級封鎖協議,即讀取資料時不加任何鎖,修改、刪除資料時,加了排它鎖

3、可重複讀、幻讀

事務a讀取記錄時事務b增加了記錄並提交,事務a再次讀取時可以看到事務b新增的記錄;

很多人容易搞混不可重複讀和幻讀,確實這兩者有些相似。但不可重複讀重點在於update和delete,而幻讀的重點在於insert。

當我們把資料庫事務級別設定為repeatable read(實際使用了上述提到的二級封鎖協議)時,事務執行查詢sql第一次讀取到資料後,就將這些資料加鎖,其它事務無法修改這些資料,但這種方法卻無法鎖住insert的資料,所以當事務a先前讀取了資料,或者修改了全部資料,事務b還是可以insert資料提交,這時事務a就會 發現莫名其妙多了一條之前沒有的資料,這就是幻讀,不能通過行鎖來避免。

所以說他只能保證被本事務操作的資料不被其他事務修改,不能保證其他事務提交新的資料

4、可序列化

幻讀,不可重複讀和髒讀都不允許;

因為獲得範圍鎖,且事務是乙個接著乙個序列執行,則保證了不會發生幻讀,但是效率會特別低

ii、資料庫事務隔離級別

iii、資料庫隔離級別與併發效能的關係

iv、設定隔離級別的原則

隔離級別越高,越能保證資料的完整性和一致性,但是對併發效能的影響也越大。

對於多數應用程式,可以優先考慮把資料庫系統的隔離級別設為read committed,它能夠避免髒讀,而且具有較好的併發效能。儘管它會導致不可重複讀、虛讀

和第二類丟失更新這些併發問題,在可能出現這類問題的個別場合,可以由應用程式採用悲觀鎖樂觀鎖來控制。

參考部落格:

表級鎖、行級鎖的介紹

MySQL 資料庫事務深入分析

推薦閱讀 吊打面試官!mysql靈魂100問,你能答出多少?只有innodb引擎支援事務,下邊的內容均以innodb引擎為預設條件 乙個事務讀取了另乙個事務未提交的資料 乙個事務對同一資料的讀取結果前後不一致。兩次讀取中間被其他事務修改了 幻讀是指事務讀取某個範圍的資料時,因為其他事務的操作導致前後...

深入分析資料庫儲存引擎

儲存引擎 1 概述 1 表處理器 mysql提過了乙個抽象層,允許不同的儲存引擎使用相同的api對錶進行訪問,這一介面稱之為表處理器,該介面通過handler的抽象類來實現,該處理器提供了一些課實現基本儲存的方法,如開啟關閉表,按照鍵進行檢索,儲存記錄及刪除記錄,2 儲存引擎 1 最近引進儲存引擎這...

深入分析列式與行式資料庫

定義 列式儲存 column based 是相對於傳統關係型資料庫的行式儲存 row based 來說的。簡單來說兩者的區別就是如何組織表。將表放入儲存系統中有兩種方法,而我們絕大部分是採用行儲存的。行儲存法是將各行放入連續的物理位置,這很像傳統的記錄和檔案系統。列儲存法是將資料按照列儲存到資料庫中...