【面試必備】快速理解數據庫事務隔離級別

事務簡介

相信用過MySQL的朋友都知道事務,咱們也經常經過這個例子來說解事務的做用:A向B轉帳,這裏能夠分爲兩步操做數據庫,A帳戶餘額減小,B帳戶餘額增長。可是,若是在A帳戶餘額減小的時候忽然出現了數據庫宕機了等狀況,是否是會出現A的餘額變少了,可是B的餘額卻沒有增長的狀況呢?答案是否認的。緣由就是數據庫支持事務(經常使用的關係型數據,如MySQL、Oracle等)。java

事務是應用程序中一系列嚴密的操做,全部操做必須成功完成,不然在每一個操做中所做的全部更改都會被撤消。也就是事務具備原子性,一個事務中的一系列的操做要麼所有成功,要麼一個都不作。mysql

事務的結束有兩種,當事務中的因此步驟所有成功執行時,事務提交。若是其中一個步驟失敗,將發生回滾操做,撤消撤消以前到事務開始時的因此操做。nginx

事務的ACID特性

這個是一個老生常談的問題,面試中也常常會問:事務的ACID特性分別是什麼?這裏的ACID分別表明四個單詞:原子性( Atomicity )、一致性( Consistency )、隔離性( Isolation )和持續性( Durability )。面試

1 、原子性。事務是數據庫的邏輯工做單位,事務中包含的各操做要麼都作,要麼都不作sql

2 、一致性。事 務執行的結果必須是使數據庫從一個一致性狀態變到另外一個一致性狀態。所以當數據庫只包含成功事務提交的結果時,就說數據庫處於一致性狀態。若是數據庫系統 運行中發生故障,有些事務還沒有完成就被迫中斷,這些未完成事務對數據庫所作的修改有一部分已寫入物理數據庫,這時數據庫就處於一種不正確的狀態,或者說是 不一致的狀態。數據庫

3 、隔離性。一個事務的執行不能受其它事務干擾。即一個事務內部的操做及使用的數據對其它併發事務是隔離的,併發執行的各個事務之間不能互相干擾。windows

4 、持續性。也稱永久性,指一個事務一旦提交,它對數據庫中的數據的改變就應該是永久性的。接下來的其它操做或故障不該該對其執行結果有任何影響。bash

事務的隔離級別

說事務隔離級別以前,先看看以下問題:session

一、髒讀(Dirty Read)併發

所謂髒讀是指一個事務中訪問到了另一個事務未提交的數據。如A事務對一條數據進行了修改,可是事務還沒提交,此時B事務讀到了A事務修改了可是未提交的數據,這就是髒讀。

二、不可重複讀(Non-repeatable read)

是指在一個事務內,屢次讀同一數據。在這個事務尚未結束時,另一個事務也訪問該同一數據。那麼,在第一個事務中的兩 次讀數據之間,因爲第二個事務的修改,那麼第一個事務兩次讀到的的數據多是不同的。這樣就發生了在一個事務內兩次讀到的數據是不同的,所以稱爲是不 可重複讀。

三、幻讀(Phantom Read)

所謂幻讀是指同一個事務內屢次查詢返回的結果集不同(好比增長了或者減小了行記錄)。好比同一個事務A內第一次查詢時候有n條記錄,可是第二次同等條件下查詢卻又n+1條記錄,這就好像產生了幻覺,爲啥兩次結果不同那。其實和不可重複讀同樣,發生幻讀的緣由也是另一個事務新增或者刪除或者修改了第一個事務結果集裏面的數據。不一樣在於不可重複讀是同一個記錄的數據內容被修改了,幻讀是數據行記錄變多了或者少了

瞭解瞭如上幾個問題以後,咱們再來看看四種事務隔離級別。

一、Read Uncommitted(讀取未提交內容)

在該隔離級別,全部事務均可以看到其餘未提交事務的執行結果。本隔離級別不多用於實際應用,由於它的性能也不比其餘級別好多少。讀取未提交的數據,也被稱之爲髒讀。

二、Read Committed(讀取提交內容)

這是大多數數據庫系統的默認隔離級別(但不是MySQL默認的)。它知足了隔離的簡單定義:一個事務只能看見已經提交事務所作的改變。這就是所謂的不可重複讀(Non-repeatable read)。

三、Repeatable Read(可重讀)

這是MySQL的默認事務隔離級別,它確保同一事務的多個實例在併發讀取數據時,會看到一樣的數據行。不過理論上,這會致使另外一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當用戶讀取某一範圍的數據行時,另外一個事務又在該範圍內插入了新行,當用戶再讀取該範圍的數據行時,會發現有新的「幻影」 行。InnoDB和Falcon存儲引擎經過多版本併發控制(MVCC,Multiversion Concurrency Control)機制解決了該問題。

四、Serializable(串行化)

這是最高的隔離級別,它經過強制事務排序,使之不可能相互衝突,從而解決幻讀問題。簡言之,它是在每一個讀的數據行上加上共享鎖。在這個級別,可能致使大量的超時現象和鎖競爭。

四種隔離級別可能出現的問題總結

除了性能最差的Serializable(串行化)隔離級別不會出現髒讀、不可重複讀、幻讀問題以外,其餘的隔離級別都存在一個或多個問題。不過MySQL的InnoDB引擎經過MVCC的方式解決了Repeatable Read的幻讀問題。

事務隔離級別

查看隔離級別

# 查看當前鏈接的隔離級別
SELECT @@session.tx_isolation;
# 查看全局的事務隔離級別
SELECT @@global.tx_isolation;
複製代碼

設置事務隔離級別

一、全局修改

在mysql的配置文件上修改,如windows的mysql.ini,Linux爲my.cnf。

#可選參數有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.
[mysqld]
transaction-isolation = REPEATABLE-READ
複製代碼

二、經過命令對當前鏈接設置

# 可選參數爲:read uncommitted、read committed、repeatable read、serializable
set session transaction isolation level xxx
複製代碼

原創聲明

本文發佈於掘金號【Happyjava】。Happy的掘金地址:juejin.im/user/5cc289…,Happy的我的博客:blog.happyjava.cn。歡迎轉載,但須保留此段聲明。

關注公衆號領資料

搜索公衆號【Happyjava】,回覆【電子書】和【視頻】,便可獲取大量優質電子書和大數據、kafka、nginx、MySQL等視頻資料

關注Happyjava公衆號
相關文章
相關標籤/搜索