事務(wù)簡介
相信用過MySQL的朋友都知道事務(wù)沉填,我們也常常通過這個例子來講解事務(wù)的作用:A向B轉(zhuǎn)賬妄壶,這里可以分為兩步操作數(shù)據(jù)庫濒持,A賬戶余額減少键耕,B賬戶余額增加。但是柑营,如果在A賬戶余額減少的時候突然出現(xiàn)了數(shù)據(jù)庫宕機(jī)了等情況屈雄,是不是會出現(xiàn)A的余額變少了,但是B的余額卻沒有增加的情況呢官套?答案是否定的酒奶。原因就是數(shù)據(jù)庫支持事務(wù)(常用的關(guān)系型數(shù)據(jù),如MySQL奶赔、Oracle等)惋嚎。
事務(wù)是應(yīng)用程序中一系列嚴(yán)密的操作,所有操作必須成功完成纺阔,否則在每個操作中所作的所有更改都會被撤消瘸彤。也就是事務(wù)具有原子性,一個事務(wù)中的一系列的操作要么全部成功笛钝,要么一個都不做质况。
事務(wù)的結(jié)束有兩種愕宋,當(dāng)事務(wù)中的所以步驟全部成功執(zhí)行時,事務(wù)提交结榄。如果其中一個步驟失敗中贝,將發(fā)生回滾操作,撤消撤消之前到事務(wù)開始時的所以操作臼朗。
事務(wù)的ACID特性
這個是一個老生常談的問題邻寿,面試中也經(jīng)常會問:事務(wù)的ACID特性分別是什么?這里的ACID分別代表四個單詞:原子性( Atomicity )视哑、一致性( Consistency )绣否、隔離性( Isolation )和持續(xù)性( Durability )。
1 挡毅、原子性蒜撮。事務(wù)是數(shù)據(jù)庫的邏輯工作單位,事務(wù)中包含的各操作要么都做跪呈,要么都不做
2 段磨、一致性。事 務(wù)執(zhí)行的結(jié)果必須是使數(shù)據(jù)庫從一個一致性狀態(tài)變到另一個一致性狀態(tài)耗绿。因此當(dāng)數(shù)據(jù)庫只包含成功事務(wù)提交的結(jié)果時苹支,就說數(shù)據(jù)庫處于一致性狀態(tài)。如果數(shù)據(jù)庫系統(tǒng) 運(yùn)行中發(fā)生故障误阻,有些事務(wù)尚未完成就被迫中斷债蜜,這些未完成事務(wù)對數(shù)據(jù)庫所做的修改有一部分已寫入物理數(shù)據(jù)庫,這時數(shù)據(jù)庫就處于一種不正確的狀態(tài)究反,或者說是 不一致的狀態(tài)策幼。
3 、隔離性奴紧。一個事務(wù)的執(zhí)行不能受其它事務(wù)干擾。即一個事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對其它并發(fā)事務(wù)是隔離的晶丘,并發(fā)執(zhí)行的各個事務(wù)之間不能互相干擾黍氮。
4 、持續(xù)性浅浮。也稱永久性沫浆,指一個事務(wù)一旦提交,它對數(shù)據(jù)庫中的數(shù)據(jù)的改變就應(yīng)該是永久性的滚秩。接下來的其它操作或故障不應(yīng)該對其執(zhí)行結(jié)果有任何影響专执。
事務(wù)的隔離級別
說事務(wù)隔離級別之前,先看看如下問題:
1郁油、臟讀(Dirty Read)
所謂臟讀是指一個事務(wù)中訪問到了另外一個事務(wù)未提交的數(shù)據(jù)本股。如A事務(wù)對一條數(shù)據(jù)進(jìn)行了修改攀痊,但是事務(wù)還沒提交,此時B事務(wù)讀到了A事務(wù)修改了但是未提交的數(shù)據(jù)拄显,這就是臟讀苟径。
2、不可重復(fù)讀(Non-repeatable read)
是指在一個事務(wù)內(nèi)躬审,多次讀同一數(shù)據(jù)棘街。在這個事務(wù)還沒有結(jié)束時,另外一個事務(wù)也訪問該同一數(shù)據(jù)承边。那么遭殉,在第一個事務(wù)中的兩 次讀數(shù)據(jù)之間,由于第二個事務(wù)的修改博助,那么第一個事務(wù)兩次讀到的的數(shù)據(jù)可能是不一樣的险污。這樣就發(fā)生了在一個事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的,因此稱為是不 可重復(fù)讀翔始。
3罗心、幻讀(Phantom Read)
所謂幻讀是指同一個事務(wù)內(nèi)多次查詢返回的結(jié)果集不一樣(比如增加了或者減少了行記錄)。比如同一個事務(wù)A內(nèi)第一次查詢時候有n條記錄城瞎,但是第二次同等條件下查詢卻又n+1條記錄渤闷,這就好像產(chǎn)生了幻覺,為啥兩次結(jié)果不一樣那脖镀。其實(shí)和不可重復(fù)讀一樣飒箭,發(fā)生幻讀的原因也是另外一個事務(wù)新增或者刪除或者修改了第一個事務(wù)結(jié)果集里面的數(shù)據(jù)。不同在于不可重復(fù)讀是同一個記錄的數(shù)據(jù)內(nèi)容被修改了蜒灰,幻讀是數(shù)據(jù)行記錄變多了或者少了
了解了如上幾個問題之后弦蹂,我們再來看看四種事務(wù)隔離級別。
1强窖、Read Uncommitted(讀取未提交內(nèi)容)
在該隔離級別凸椿,所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果。本隔離級別很少用于實(shí)際應(yīng)用翅溺,因為它的性能也不比其他級別好多少脑漫。讀取未提交的數(shù)據(jù),也被稱之為臟讀咙崎。
2优幸、Read Committed(讀取提交內(nèi)容)
這是大多數(shù)數(shù)據(jù)庫系統(tǒng)的默認(rèn)隔離級別(但不是MySQL默認(rèn)的)。它滿足了隔離的簡單定義:一個事務(wù)只能看見已經(jīng)提交事務(wù)所做的改變褪猛。這就是所謂的不可重復(fù)讀(Non-repeatable read)网杆。
3、Repeatable Read(可重讀)
這是MySQL的默認(rèn)事務(wù)隔離級別,它確保同一事務(wù)的多個實(shí)例在并發(fā)讀取數(shù)據(jù)時碳却,會看到同樣的數(shù)據(jù)行队秩。不過理論上,這會導(dǎo)致另一個棘手的問題:幻讀 (Phantom Read)追城。簡單的說刹碾,幻讀指當(dāng)用戶讀取某一范圍的數(shù)據(jù)行時,另一個事務(wù)又在該范圍內(nèi)插入了新行座柱,當(dāng)用戶再讀取該范圍的數(shù)據(jù)行時迷帜,會發(fā)現(xiàn)有新的“幻影” 行。InnoDB和Falcon存儲引擎通過多版本并發(fā)控制(MVCC色洞,Multiversion Concurrency Control)機(jī)制解決了該問題戏锹。
4、Serializable(串行化)
這是最高的隔離級別火诸,它通過強(qiáng)制事務(wù)排序锦针,使之不可能相互沖突,從而解決幻讀問題置蜀。簡言之奈搜,它是在每個讀的數(shù)據(jù)行上加上共享鎖。在這個級別盯荤,可能導(dǎo)致大量的超時現(xiàn)象和鎖競爭馋吗。
四種隔離級別可能出現(xiàn)的問題總結(jié)
除了性能最差的Serializable(串行化)隔離級別不會出現(xiàn)臟讀、不可重復(fù)讀秋秤、幻讀問題之外宏粤,其他的隔離級別都存在一個或多個問題。不過MySQL的InnoDB引擎通過MVCC的方式解決了Repeatable Read的幻讀問題灼卢。
查看隔離級別
# 查看當(dāng)前連接的隔離級別SELECT @@session.tx_isolation;# 查看全局的事務(wù)隔離級別SELECT @@global.tx_isolation;復(fù)制代碼
設(shè)置事務(wù)隔離級別
1绍哎、全局修改
在mysql的配置文件上修改,如windows的mysql.ini鞋真,Linux為my.cnf崇堰。
#可選參數(shù)有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.[mysqld]transaction-isolation = REPEATABLE-READ復(fù)制代碼
2、通過命令對當(dāng)前連接設(shè)置
# 可選參數(shù)為:read uncommitted涩咖、read committed赶袄、repeatable read、serializablesetsession transaction isolation level xxx
關(guān)注公眾號領(lǐng)資料
搜索公眾號【Java耕耘者】,回復(fù)【Java】抠藕,即可獲取大量優(yōu)質(zhì)電子書和Java、kafka蒋困、nginx盾似、MySQL等視頻資料
作者:happyjava
鏈接:https://juejin.im/post/5d5575dde51d4561a705badd