MySQL系列 3事物隔離

2021-10-09 08:35:13 字數 2459 閱讀 3061

事務是用來保證資料庫一致性的關鍵技術。事物內的資料庫操作,要麼全部成功,要麼全部失敗。在mysql中,事務支援是在引擎層實現的。

本篇文章裡,將會以innodb為例,剖析mysql在事務支援方面的特定實現。

隔離性與隔離級別

提到事務,你肯定會想到acid(atomicity、consistency、isolation、durability,即原子性、一致性、隔離性、永續性)。

本章講解的就是其中i,也就是「隔離性」:

當資料庫上有多個事務同時執行的時候,就可能出現髒讀(dirty read)、不可重複讀(non-repeatable read)、幻讀(phantom read)的問題,為了解決這些問題,就有了「隔離級別」的概念。可以用 show variables like 『transaction_isolation』; 來檢視當前的隔離級別。

下面簡單介紹一下四種隔離級別。

· read uncommitted(讀未提交):事務還沒提交時,變動就能被別的事務看到。

· read committed(讀提交): 事物提交後,變動才能被別的事物看到。

· repeatable read(可重複讀):事務執行過程中看到的資料,總是跟這個事務在啟動時看到的資料是一致的。在可重複讀隔離級別下,未提交變更對其他事務也是不可見的。

· seriaizable(序列化):對於每一行記錄,都會加鎖(「寫」會加「寫鎖」,「讀」會加「讀鎖」)。當出現讀寫鎖衝突的時候,後訪問的事務必須等前乙個事務執行完成,才能繼續執行。

大致實現邏輯:

資料庫裡面會建立乙個檢視,訪問的時候以檢視的邏輯結果為準。

在「可重複讀」隔離級別下,這個檢視是在事務啟動時建立的,整個事務存在期間都用這個檢視。

在「讀提交」隔離級別下,這個檢視是在每個sql語句開始執行的時候建立的。

這裡需要注意的是,「讀未提交」隔離級別下直接返回記錄上的最新值,沒有檢視概念;而「序列化」隔離級別下直接用加鎖的方式來避免並行訪問。

事務的啟動方式

1.顯式啟動事務語句, begin 或 start transaction。提交語句是commit,回滾語句是rollback。

2.set autocommit=0,這個命令會將這個執行緒的自動提交關掉。意味著如果你只執行乙個select語句,這個事務就啟動了,而且不會自動提交。這個事務持續存在直到你主動執行commit 或 rollback 語句,或者斷開連線。

建議使用set autocommit=1, 通過顯式語句的方式來啟動事務。(select @@autocommit; 檢視當前值)

有的開發會糾結「多一次互動」的問題。對於乙個需要頻繁使用事務的業務,第二種方式每個事務在開始時都不需要主動執行一次 「begin」,減少了語句的互動次數。如果你也有這個顧慮,我建議你使用commit work and chain語法。

在autocommit為1的情況下,用begin顯式啟動的事務,執行commit work and chain則提交事務並自動啟動下乙個事務。

可以在information_schema庫的innodb_trx這個表中查詢長事務,比如下面這個語句,用於查詢持續時間超過60s的事務。

select * from information_schema.innodb_trx where time_to_sec(timediff(now(),trx_started))>60

mvcc多版本併發控制

指的是一條記錄在系統中可以存在多個版本,每次修改記錄都會儲存這條記錄被修改的之前的版本,多版本之間串聯起來就形成了一條版本鏈。

mvcc在很多情況下避免了加鎖操作,因此開銷更低,實現了非阻塞的讀操作,寫操作只鎖定必要的行。

innodb的mvcc,是通過在每行記錄後儲存2個隱藏的列實現的。這兩個列,乙個儲存行的建立時間,乙個儲存行的過期時間(或刪除時間)。儲存的是系統版本號。

每開始乙個新事物,系統版本號都會自動遞增。事物開始時的系統版本號會作為事物的版本號,用來和查詢到的每行記錄版本號做比較。

下面是可重複讀隔離級別下,mvcc實現

select

讀取建立版本小於或等於當前事務版本號,並且刪除版本為空或大於當前事務版本號的記錄。這樣可以保證在讀取之前記錄是存在的

insert

將當前事務的版本號儲存至行的建立版本號

update

新插入一行,儲存當前系統版本號作為行版本號,同時將原記錄行的刪除版本號設定為當前事務版本號

delete

將當前事務的版本號儲存至行的刪除版本號

擴充套件

如何避免長事務對業務的影響?

業務連線資料庫的時候,根據業務本身的預估,通過set max_execution_time命令,來控制每個語句執行的最長時間,避免單個語句意外執行太長時間。

監控 information_schema.innodb_trx表,設定長事務閾值,超過就報警/或者kill。

使用監控工具。

mysql事物隔離級別

複習鞏固加深印象 一。事務 acid原子性,隔離性,一致性,永續性 二。事務隔離級別 通常併發事務處理 1 寫 寫,存在更新丟失問題 2 讀 寫,有隔離性問題,可能遇到髒讀,不可重複讀,幻讀 其中 1.髒讀 a事務讀到b未提交的資料 2.不可重複讀 a事務第二次讀時讀到了b事務提交的寫資料,可能導致...

MySQL事物隔離級別

mysql其實是分為server層和引擎層。server層包括 聯結器 分析器 優化器 執行器 以及查詢快取。在這裡執行的一些mysql自己的一些邏輯,比如函式 儲存過程 檢視 觸發器,但是還沒有真正的去資料檔案中讀取資料。引擎層 innodb myisam memory 負責資料的查詢和提取。現在...

mysql事物隔離級別

事物是區分檔案儲存系統與nosql資料庫重要特性之一,其存在的意義是為了保證即使在併發情況下也能正確的執行crud操作。怎樣才算是正確的呢?這時提出了事物需要保證的四個特性即acid a 原子性 atomicity c 一致性 consistency i 隔離性 isolation d 永續性 du...