自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

事務(wù)、隔離級(jí)別和并發(fā)一致性問(wèn)題

數(shù)據(jù)庫(kù)
事務(wù)本質(zhì)上就是一系列邏輯操作,不同數(shù)據(jù)庫(kù)、不同存儲(chǔ)引擎對(duì)事務(wù)的支持強(qiáng)度都是不一樣的。比如Mysql數(shù)據(jù)庫(kù)InnoDB引擎天然支持事務(wù),而Myisam引擎則不支持事務(wù)。

?數(shù)據(jù)庫(kù)的事務(wù)一直以來(lái)是數(shù)據(jù)庫(kù)最核心的基礎(chǔ)知識(shí),熟悉事務(wù)知識(shí)是深入學(xué)習(xí)數(shù)據(jù)庫(kù)的前提;同時(shí),數(shù)據(jù)庫(kù)的事務(wù)也是互聯(lián)網(wǎng)面試最最最常問(wèn)的知識(shí)之一。

本文我們將從以下幾個(gè)角度深入分析:

  • 事務(wù)的四大特性
  • 數(shù)據(jù)庫(kù)并發(fā)環(huán)境下的一致性問(wèn)題
  • 數(shù)據(jù)庫(kù)的隔離級(jí)別分別所解決的一致性問(wèn)題。

話不多說(shuō),小伙伴們,上車吧!

事務(wù)

什么是事務(wù)?

事務(wù)是數(shù)據(jù)庫(kù)系統(tǒng)里面非常重要的術(shù)語(yǔ)。它可以由一行簡(jiǎn)單的SQL來(lái)實(shí)現(xiàn),也可以由一組復(fù)雜的SQL來(lái)實(shí)現(xiàn)。對(duì)于MySQL來(lái)說(shuō),有兩種事務(wù)實(shí)現(xiàn)方式,一種是顯式事務(wù),另一種則是隱式事務(wù)。顯式事務(wù)需要我們自己手動(dòng)使用begin或start transaction開啟事務(wù),執(zhí)行完中間的SQL語(yǔ)句后使用commit提交事務(wù),即手動(dòng)提交。

InnoDB默認(rèn)為隱式事務(wù),即自動(dòng)提交,每一行insert、update、delete的SQL語(yǔ)句操作都默認(rèn)為一個(gè)獨(dú)立的事務(wù)。如果想關(guān)閉自動(dòng)提交,可以set autocommit = 0來(lái)實(shí)現(xiàn)。

本質(zhì)上來(lái)說(shuō),事務(wù)其實(shí)就是一系列邏輯操作,為了保證這一系列邏輯操作能夠被準(zhǔn)確、統(tǒng)一、安全地執(zhí)行,就需要通過(guò)規(guī)范和技術(shù)來(lái)實(shí)現(xiàn)事務(wù),讓事務(wù)具備特性。

事務(wù)有什么特性?

1. 原子性(Atomicity)

一個(gè)事務(wù)被視為不可分割的最小單元,一個(gè)事務(wù)的所有操作要么全部提交成功,要么全部失敗回滾。當(dāng)你為一組行為開啟事務(wù)時(shí),這組行為的全部操作要么同時(shí)成功,要么同時(shí)失敗,不存在某一步行為成功執(zhí)行而另一步執(zhí)行失敗的場(chǎng)景。一旦某個(gè)行為操作失敗,那么這組行為里包括執(zhí)行成功和執(zhí)行失敗的會(huì)全部回滾,就像什么事都沒(méi)發(fā)生過(guò)一樣。

2. 隔離性(Isolation)

一個(gè)事務(wù)所做的修改在最終提交以前,對(duì)其它事務(wù)是不可見的。

3. 一致性(Consistency)

數(shù)據(jù)庫(kù)的數(shù)據(jù)在事務(wù)執(zhí)行前后都保持一致性狀態(tài)。在一致性狀態(tài)下,所有事務(wù)對(duì)同一個(gè)數(shù)據(jù)的讀取結(jié)果都是相同的。不能存在同一個(gè)事務(wù)對(duì)某一組數(shù)據(jù)前后兩次讀取的內(nèi)容不一致的場(chǎng)景。

4. 持久性(Durability)

一旦事務(wù)提交,則其所做的修改將會(huì)永遠(yuǎn)保存到數(shù)據(jù)庫(kù)中。即使系統(tǒng)發(fā)生崩潰,事務(wù)執(zhí)行的結(jié)果也不能丟失。

對(duì)于一個(gè)事務(wù),想要實(shí)現(xiàn)它必須遵循以上ACID四個(gè)特性,也就是這四個(gè)特性必須全部得到滿足才可以稱之為一個(gè)完整的數(shù)據(jù)庫(kù)“事務(wù)”。

那么InnoDB如何去實(shí)現(xiàn)這四個(gè)特性呢?不同的特性其實(shí)有不同的實(shí)現(xiàn)方式:

圖片

并發(fā)一致性問(wèn)題

什么是數(shù)據(jù)庫(kù)的并發(fā)一致性問(wèn)題?

并發(fā)一致性問(wèn)題,指的是在并發(fā)環(huán)境下,因?yàn)槭聞?wù)的隔離性很難保證,所以會(huì)出現(xiàn)很多并發(fā)問(wèn)題。

數(shù)據(jù)庫(kù)的并發(fā)一致性問(wèn)題一共有三種,分別是:

1. 臟讀(Dirty Read)

指的是事務(wù)A讀取到了事務(wù)B已經(jīng)修改但是還未提交的數(shù)據(jù)。

假設(shè)A和B同時(shí)讀取一個(gè)數(shù)據(jù),事務(wù)A讀取到這個(gè)數(shù)據(jù)的值為10,隨后將其值修改為20,按道理,事務(wù)A對(duì)這個(gè)數(shù)據(jù)的修改在事務(wù)未提交之前是不會(huì)被其他事務(wù)看到的,但是由于數(shù)據(jù)庫(kù)的隔離性未能保證,此時(shí)事務(wù)B也去讀取這個(gè)數(shù)據(jù)的值,就會(huì)直接讀取到事務(wù)A修改完之后的值20,那么此時(shí)如果事務(wù)A進(jìn)行了數(shù)據(jù)的回滾,不提交了。那么事務(wù)B最終讀取到的就是一個(gè)過(guò)期的值20。

這種情況就稱為臟讀。

圖片圖片

2. 不可重復(fù)讀(Nnrepeatable Read)

指的是在一個(gè)事務(wù)里面兩次讀取到的內(nèi)容不一樣。

事務(wù)B讀取到某個(gè)數(shù)據(jù)S的值為10,隨后事務(wù)A將S的值修改為20。如果B再次讀取這個(gè)數(shù)據(jù),讀取到的值就變?yōu)?0。此時(shí)讀取的結(jié)果和第一次讀取的結(jié)果不同,這就是不可重復(fù)讀。按道理,事務(wù)B都還沒(méi)有提交,所讀取到的數(shù)據(jù)應(yīng)該是對(duì)別的事務(wù)不可見的,換句話來(lái)說(shuō)應(yīng)該是安全的。但是由于并發(fā)環(huán)境下事務(wù)的隔離型未能滿足,多個(gè)事務(wù)在某一個(gè)相同時(shí)刻對(duì)同一個(gè)數(shù)據(jù)進(jìn)行修改,就會(huì)出現(xiàn)這樣的并發(fā)沖突問(wèn)題。

圖片

3. 幻讀(Phantom Read)

指的是在一個(gè)事務(wù)內(nèi)查詢某個(gè)數(shù)據(jù)范圍的數(shù)據(jù),如果出現(xiàn)了兩次查詢的結(jié)果不一樣,就稱為“幻讀”。

事務(wù)A根據(jù)條件查詢到某個(gè)范圍的數(shù)據(jù)[10,20,30,40.50],此時(shí)B在這個(gè)符合條件的范圍內(nèi)插入新的數(shù)據(jù),A再次讀取這個(gè)范圍的數(shù)據(jù)后,發(fā)現(xiàn)該范圍多出了一條數(shù)據(jù)60,此時(shí)就發(fā)生了“幻讀”現(xiàn)象?;米x現(xiàn)象發(fā)生的本質(zhì),也是由于事務(wù)的隔離型未能保證導(dǎo)致的。

圖片

所以,MySQL如何解決并發(fā)一致性問(wèn)題?

首先強(qiáng)調(diào)一下,MySQL并不等于InnoDB。

InnoDB是MySQL5.5版本之后默認(rèn)使用的存儲(chǔ)引擎。InnoDB使用MVCC可以解決臟讀和不可重復(fù)讀問(wèn)題。但是,MVCC并不是唯一可以解決并發(fā)一致性問(wèn)題的措施。MVCC本質(zhì)上是一種樂(lè)觀鎖,通過(guò)比較不同事務(wù)的版本號(hào)的方式來(lái)解決問(wèn)題。可以使用樂(lè)觀鎖,那么一樣也可以使用悲觀鎖。MySQL的其他存儲(chǔ)引擎比如Myisam甚至無(wú)法使用事務(wù),所以它一般用鎖來(lái)解決并發(fā)一致性問(wèn)題。

在這里,我先不贅述InnoDB的MVCC和MySQL各種各樣的鎖,我們放到之后的文章來(lái)講。本篇文章主要強(qiáng)調(diào)事務(wù)本身。

隔離級(jí)別

什么是數(shù)據(jù)庫(kù)的隔離級(jí)別?

指的是實(shí)現(xiàn)了數(shù)據(jù)庫(kù)中的安全級(jí)別。從對(duì)ACID的實(shí)現(xiàn)程度上分為四個(gè)隔離級(jí)別。隔離級(jí)別越高的數(shù)據(jù)庫(kù)越安全,能解決的并發(fā)一致性問(wèn)題也就越多。

那么數(shù)據(jù)庫(kù)有幾種隔離級(jí)別呢?

1. 未提交讀(Read Uncommitted)

事務(wù)中的修改,即使沒(méi)有提交,對(duì)其它事務(wù)也是可見的。該隔離級(jí)別會(huì)發(fā)生臟讀、不可重復(fù)讀、幻讀。所以是最差的一個(gè)隔離級(jí)別。

2. 提交讀(Read Committed)

一個(gè)事務(wù)只能讀取已經(jīng)提交的事務(wù)所做的修改。換句話說(shuō),一個(gè)事務(wù)所做的修改在提交之前對(duì)其它事務(wù)是不可見的,所以該隔離級(jí)別解決了臟讀問(wèn)題,也就是說(shuō),當(dāng)你的數(shù)據(jù)庫(kù)實(shí)現(xiàn)到了提交讀這個(gè)隔離級(jí)別時(shí),臟讀現(xiàn)象就不會(huì)再發(fā)生。

3. 可重復(fù)讀(Repeatable Read)

保證在同一個(gè)事務(wù)中多次讀取同一數(shù)據(jù)的結(jié)果是一樣的。這是第三個(gè)隔離級(jí)別,也是InnoDB默認(rèn)實(shí)現(xiàn)的隔離級(jí)別。

當(dāng)你的數(shù)據(jù)庫(kù)實(shí)現(xiàn)到了提交讀這個(gè)隔離級(jí)別時(shí),臟讀和不可重復(fù)讀現(xiàn)象就都不會(huì)再發(fā)生。

4. 可串行化(Serializable)

強(qiáng)制事務(wù)串行執(zhí)行,這樣多個(gè)事務(wù)互不干擾,自然而然就不會(huì)出現(xiàn)并發(fā)一致性問(wèn)題。

該隔離級(jí)別需要加鎖實(shí)現(xiàn),因?yàn)橐褂眉渔i機(jī)制保證同一時(shí)間只有一個(gè)事務(wù)執(zhí)行。

因?yàn)榭纱谢谴袌?zhí)行,所以不會(huì)有并發(fā)問(wèn)題。這也是最安全的,第四個(gè)隔離級(jí)別。

總結(jié)一下:

  • 讀未提交就是一種最差的數(shù)據(jù)庫(kù)隔離級(jí)別, 說(shuō)明你這個(gè)數(shù)據(jù)庫(kù)在多事務(wù)的時(shí)候非常不安全;
  • 提交讀能解決臟讀問(wèn)題;
  • 可重復(fù)讀能解決不可重復(fù)讀和臟讀問(wèn)題;
  • 串行化能解決臟讀、不可重復(fù)讀、幻讀問(wèn)題。

為什么InnoDB不默認(rèn)實(shí)現(xiàn)可串行化?

數(shù)據(jù)庫(kù)提出了這四種隔離級(jí)別分別來(lái)解決不同的并發(fā)一致性問(wèn)題。

但是,難道隔離級(jí)別越高就越好嗎?對(duì)于各大編程語(yǔ)言,不僅僅要考慮“安全”,還要考慮“性能”,對(duì)于數(shù)據(jù)庫(kù)一樣如此。

隔離級(jí)別越高,就代表著越安全,但是同時(shí)性能效率也就越低。你想想,當(dāng)你的數(shù)據(jù)庫(kù)做到了串行化,就意味沒(méi)有并發(fā)問(wèn)題產(chǎn)生。但是此時(shí)你讀取的數(shù)據(jù)身上掛著一把鎖,一個(gè)數(shù)據(jù)同一時(shí)刻只能被一個(gè)事務(wù)訪問(wèn),那么剩下的事務(wù)獲取不到就只能排隊(duì)。實(shí)際生產(chǎn)環(huán)境中往往都是在并發(fā)環(huán)境中對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作,業(yè)務(wù)高峰的時(shí)候甚至?xí)袔兹f(wàn)、幾十萬(wàn)個(gè)事務(wù)同時(shí)存在,所以串行化往往得不到業(yè)務(wù)上的滿足。這就需要在“安全”和“性能”之間做一個(gè)衡量,于是MySQL的InnoDB存儲(chǔ)引擎默認(rèn)實(shí)現(xiàn)的隔離級(jí)別為“可重復(fù)讀”,而非可串行化。

總結(jié)

事務(wù)本質(zhì)上就是一系列邏輯操作,不同數(shù)據(jù)庫(kù)、不同存儲(chǔ)引擎對(duì)事務(wù)的支持強(qiáng)度都是不一樣的。比如Mysql數(shù)據(jù)庫(kù)InnoDB引擎天然支持事務(wù),而Myisam引擎則不支持事務(wù)。

數(shù)據(jù)庫(kù)事務(wù)只有滿足了ACID四大特性,才能安全的被我們執(zhí)行。如果是在某一個(gè)時(shí)刻只有一個(gè)事務(wù)在操作,那么就不會(huì)出現(xiàn)并發(fā)一致性問(wèn)題,那么ACID就很容易滿足。因?yàn)楦綦x性是可以滿足的,我們只要滿足了原子性,就可以滿足一致性。

但是在多事務(wù)的并發(fā)環(huán)境下,由于事務(wù)的隔離性很難滿足,就會(huì)產(chǎn)生臟讀、不可重復(fù)讀、幻讀的并發(fā)一致性問(wèn)題。為了解決這些并發(fā)一致性問(wèn)題,數(shù)據(jù)庫(kù)系統(tǒng)規(guī)范了四個(gè)隔離級(jí)別:未提交讀、提交讀、可重復(fù)讀、可串行化。

隔離級(jí)別越高,并發(fā)環(huán)境下數(shù)據(jù)庫(kù)越安全,但是性能也越低。所以為了權(quán)衡安全和性能,InnoDB默認(rèn)實(shí)現(xiàn)的隔離級(jí)別是“可重復(fù)讀”。

那么如何實(shí)現(xiàn)可重復(fù)讀呢?可以使用鎖,也可以使用MVCC。?

責(zé)任編輯:趙寧寧 來(lái)源: fancyJava
相關(guān)推薦

2023-12-19 09:43:43

MongoDB并發(fā)

2024-04-11 13:45:14

Redis數(shù)據(jù)庫(kù)緩存

2024-11-14 07:10:00

2016-11-29 09:00:19

分布式數(shù)據(jù)一致性CAS

2022-09-13 13:49:05

數(shù)據(jù)庫(kù)隔離

2019-05-27 09:00:00

蘇寧智慧零售平臺(tái)數(shù)據(jù)庫(kù)

2019-09-08 22:45:48

并發(fā)扣款一致性冪等性

2022-09-06 15:30:20

緩存一致性

2023-12-05 08:02:26

MySQL隔離

2019-09-18 08:41:53

并發(fā)扣減一致性redis

2017-09-04 14:46:10

分布式事務(wù)問(wèn)題

2023-12-01 13:51:21

數(shù)據(jù)一致性數(shù)據(jù)庫(kù)

2019-02-13 11:04:42

系統(tǒng)緩存軟件

2023-04-13 08:15:47

Redis緩存一致性

2025-03-10 09:20:00

庫(kù)存異常Redis架構(gòu)

2020-09-04 06:32:08

緩存數(shù)據(jù)庫(kù)接口

2025-03-24 10:17:01

2012-09-24 09:35:42

分布式系統(tǒng)

2022-10-19 12:22:53

并發(fā)扣款一致性

2021-09-08 11:03:13

緩存數(shù)據(jù)庫(kù)性能
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)