資料庫 事務與隔離級別

2021-09-25 11:07:08 字數 2689 閱讀 9594

事務概述

redo log概述

undo log概述

事務控制語句

配置引數

控制語句

事務隔離級別

隔離級別簡介

mvcc併發控制

鎖型別簡介

事務是作為單個邏輯操作單元的一系列操作。事務可以包含一條或多條sql語句,所有的語句被當做乙個操作單元,要麼全部成功、要麼全部失敗(即作為乙個原子操作)。

資料庫中的事務要滿足acid特性:

redo log概述

mysql在執行事務時,先將事務中的sql語句涉及到的所有資料庫操作記錄到『redo log』中,然後將操作同步到資料庫檔案中(在實際修改資料庫前,先把操作記錄到日誌中)。這樣即使資料修改到一半被打斷(如當機等),也能通過日誌將剩餘的操作同步到資料庫中。

redo能夠實現原子性(a),保證乙個事務中所有sql被當成乙個執行單元。『redo log』是物理日誌,其中記錄的是資料庫對頁的操作,而非邏輯上的增刪改查;因此重做日誌具有冪等性。

『redo log』由兩部分組成:

多個日誌記錄檔案組成乙個log group(重做日誌組),當組中的第乙個logfile被寫滿時,就寫下乙個;當組內的所有logfile都寫滿時,就重新從第乙個logfile寫(覆蓋原來的)。為了保證進一步的安全,日誌可儲存在raid1等冗餘裝置上。

undo log概述

『undo log』可看成資料修改前的備份。若事務執行過程中,有一條sql無法成功執行,需要進行回滾時,就需要根據『undo log』進行撤銷,將所有修改過的資料從邏輯上恢復到事務開始前的樣子。

『undo log』是邏輯日誌,若前面inert 10條記錄,則undo時即delete 10條;因此不具有冪等性。

配置引數

控制語句

預設情況時,事務是自動提交的(執行sql語句後,自動執行commit):

show global variable like 'autocommit%'

show session variable like 'autocommit%'

可通過控制語句,顯式地控制事務:

對於mysql伺服器,可以有若干個客戶端與其連線(每個連線稱為乙個會話session)。不同的會話可以同時傳送各種請求(事務),為了避免事務之間互相影響,並提高系統的併發處理能力,提出了各種隔離級別。

隔離級別簡介

事務通過鎖機制滿足隔離性,事務的隔離級別決定了事務間的隔離性:

show variable like 'tx_isolation'可檢視設定的隔離級別,my.cnf配置檔案中設定transaction_isolation=repeatable-read

innodb中採用一致性非鎖定讀機制(『可重讀』和『讀提交』隔離級別下)提高資料庫併發性:讀取資料時(使用非鎖定讀),若當前行被施加了排他鎖,則不會等待鎖釋放,而是去讀取乙個快照資料。

因此會引起幻讀現象:即同乙個事務中,前後兩條查詢語句看到的資料可能不同(多出、或減少條目)。

隔離級別越高,隔離性越強,遇到的問題越少,併發越弱:

標題髒讀

不可重讀

幻讀讀未提交√√

√讀提交×√

√可重讀××

√序列化××

×mvcc併發控制

mvcc(multi-version concurrency control)多版本併發控制,用於『可重複讀』和『讀已提交』隔離級別的處理。通過儲存資料庫某個時間的快照,來實現的。

每一行資料儲存兩個隱藏的列:當前行建立時的版本號和刪除時的版本號(未刪除時為空)。版本號為系統的版本號,新事務開始時自動遞增(事務開始時系統版本號為事務的版本號)。

增刪改查時的版本號處理

插入資料時(事務版本設為1):記錄的版本號為當前事務的版本號

idname

create-version

delete-version

1oldname

1更新資料時(事務版本設為2):先標記舊的資料為已刪除(刪除版本號為當前事務版本號),然後插入一條新的記錄(更新後的資料);

idname

create-version

delete-version

1oldname12

1new-name

2刪除資料時(事務版本設為3):刪除版本號記為當前事務版本號

idname

create-version

delete-version

1new-name23

查詢操作:只有符合條件的記錄才會被查詢出來

鎖型別簡介

為保證資料訪問的一致性、有效性,就需要鎖;同時鎖衝突也是影響資料庫併發效能的乙個重要因素:

資料庫的增刪改操作預設都會加排他鎖,而查詢不會加任何鎖。

悲觀鎖與樂觀鎖是兩種常見的資源併發鎖設計思路。通常所說的「一鎖二查三更新」即使用的是悲觀鎖。

樂觀鎖在不發生取鎖失敗的情況下開銷比悲觀鎖小,但是一旦發生失敗回滾開銷則比較大,因此樂觀鎖適用於寫比較少的情況下,即衝突真的很少發生的時候,這樣可以省去了鎖的開銷,加大了系統的整個吞吐量。經常產生衝突,上層需要不斷重試情況,樂觀鎖反倒是降低了效能,這種情況下用悲觀鎖就比較合適。

資料庫事務隔離級別

資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable,這四個級別可以逐個解決髒讀 不可重複讀 幻讀這幾類問題。可能出現 不會出現 髒讀不可重複讀 幻讀read uncommitted rea...

資料庫事務隔離級別

資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable,這四個級別可以逐個解決髒讀 不可重複讀 幻讀這幾類問題。可能出現 不會出現 髒讀不可重複讀 幻讀read uncommitted rea...

資料庫事務隔離級別

資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable 這四個級別可以逐個解決髒讀 不可重複讀 幻讀 這幾類問題。可能出現 不會出現 髒讀不可重複讀 幻讀read uncommitted re...