欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

MySQL中什么是事務(wù)與鎖

這篇文章給大家介紹MySQL中什么是事務(wù)與鎖,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

我們提供的服務(wù)有:網(wǎng)站建設(shè)、成都做網(wǎng)站、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、三明ssl等。為上1000家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的三明網(wǎng)站制作公司

MySQL 中事務(wù)的實(shí)現(xiàn)

在關(guān)系型數(shù)據(jù)庫中,事務(wù)的重要性不言而喻,只要對(duì)數(shù)據(jù)庫稍有了解的人都知道事務(wù)具有 ACID 四個(gè)基本屬性,而我們不知道的可能就是數(shù)據(jù)庫是如何實(shí)現(xiàn)這四個(gè)屬性的;在這篇文章中,我們將對(duì)事務(wù)的實(shí)現(xiàn)進(jìn)行分析,嘗試?yán)斫鈹?shù)據(jù)庫是如何實(shí)現(xiàn)事務(wù)的,當(dāng)然我們也會(huì)在文章中簡單對(duì) MySQL 中對(duì) ACID 的實(shí)現(xiàn)進(jìn)行簡單的介紹。

事務(wù)其實(shí)就是并發(fā)控制的基本單位;相信我們都知道,事務(wù)是一個(gè)序列操作,其中的操作要么都執(zhí)行,要么都不執(zhí)行,它是一個(gè)不可分割的工作單位;數(shù)據(jù)庫事務(wù)的 ACID 四大特性是事務(wù)的基礎(chǔ),了解了 ACID 是如何實(shí)現(xiàn)的,我們也就清除了事務(wù)的實(shí)現(xiàn),接下來我們將依次介紹數(shù)據(jù)庫是如何實(shí)現(xiàn)這四個(gè)特性的。

原子性

在學(xué)習(xí)事務(wù)時(shí),經(jīng)常有人會(huì)告訴你,事務(wù)就是一系列的操作,要么全部都執(zhí)行,要都不執(zhí)行,這其實(shí)就是對(duì)事務(wù)原子性的刻畫;雖然事務(wù)具有原子性,但是原子性并不是只與事務(wù)有關(guān)系,它的身影在很多地方都會(huì)出現(xiàn)。

由于操作并不具有原子性,并且可以再分為多個(gè)操作,當(dāng)這些操作出現(xiàn)錯(cuò)誤或拋出異常時(shí),整個(gè)操作就可能不會(huì)繼續(xù)執(zhí)行下去,而已經(jīng)進(jìn)行的操作造成的副作用就可能造成數(shù)據(jù)更新的丟失或者錯(cuò)誤。

事務(wù)其實(shí)和一個(gè)操作沒有什么太大的區(qū)別,它是一系列的數(shù)據(jù)庫操作(可以理解為 SQL)的集合,如果事務(wù)不具備原子性,那么就沒辦法保證同一個(gè)事務(wù)中的所有操作都被執(zhí)行或者未被執(zhí)行了,整個(gè)數(shù)據(jù)庫系統(tǒng)就既不可用也不可信。

回滾日志

想要保證事務(wù)的原子性,就需要在異常發(fā)生時(shí),對(duì)已經(jīng)執(zhí)行的操作進(jìn)行回滾,而在 MySQL 中,恢復(fù)機(jī)制是通過回滾日志(undo log)實(shí)現(xiàn)的,所有事務(wù)進(jìn)行的修改都會(huì)先記錄到這個(gè)回滾日志中,然后在對(duì)數(shù)據(jù)庫中的對(duì)應(yīng)行進(jìn)行寫入。

這個(gè)過程其實(shí)非常好理解,為了能夠在發(fā)生錯(cuò)誤時(shí)撤銷之前的全部操作,肯定是需要將之前的操作都記錄下來的,這樣在發(fā)生錯(cuò)誤時(shí)才可以回滾。

回滾日志除了能夠在發(fā)生錯(cuò)誤或者用戶執(zhí)行 ROLLBACK 時(shí)提供回滾相關(guān)的信息,它還能夠在整個(gè)系統(tǒng)發(fā)生崩潰、數(shù)據(jù)庫進(jìn)程直接被殺死后,當(dāng)用戶再次啟動(dòng)數(shù)據(jù)庫進(jìn)程時(shí),還能夠立刻通過查詢回滾日志將之前未完成的事務(wù)進(jìn)行回滾,這也就需要回滾日志必須先于數(shù)據(jù)持久化到磁盤上,是我們需要先寫日志后寫數(shù)據(jù)庫的主要原因。

回滾日志并不能將數(shù)據(jù)庫物理地恢復(fù)到執(zhí)行語句或者事務(wù)之前的樣子;它是邏輯日志,當(dāng)回滾日志被使用時(shí),它只會(huì)按照日志邏輯地將數(shù)據(jù)庫中的修改撤銷掉看,可以理解為,我們?cè)谑聞?wù)中使用的每一條 INSERT 都對(duì)應(yīng)了一條 DELETE,每一條 UPDATE 也都對(duì)應(yīng)一條相反的 UPDATE 語句。

在這里,我們并不會(huì)介紹回滾日志的格式以及它是如何被管理的,本文重點(diǎn)關(guān)注在它到底是一個(gè)什么樣的東西,究竟解決了、如何解決了什么樣的問題,如果想要了解具體實(shí)現(xiàn)細(xì)節(jié)的讀者,相信網(wǎng)絡(luò)上關(guān)于回滾日志的文章一定不少。

事務(wù)的狀態(tài)

因?yàn)槭聞?wù)具有原子性,所以從遠(yuǎn)處看的話,事務(wù)就是密不可分的一個(gè)整體,事務(wù)的狀態(tài)也只有三種:Active、Commited 和 Failed,事務(wù)要不就在執(zhí)行中,要不然就是成功或者失敗的狀態(tài):

但是如果放大來看,我們會(huì)發(fā)現(xiàn)事務(wù)不再是原子的,其中包括了很多中間狀態(tài),比如部分提交,事務(wù)的狀態(tài)圖也變得越來越復(fù)雜。

事務(wù)的狀態(tài)圖以及狀態(tài)的描述取自 Database System Concepts 一書中第 14 章的內(nèi)容。

Active:事務(wù)的初始狀態(tài),表示事務(wù)正在執(zhí)行;

Partially Commited:在最后一條語句執(zhí)行之后;

Failed:發(fā)現(xiàn)事務(wù)無法正常執(zhí)行之后;

Aborted:事務(wù)被回滾并且數(shù)據(jù)庫恢復(fù)到了事務(wù)進(jìn)行之前的狀態(tài)之后;

Commited:成功執(zhí)行整個(gè)事務(wù);

雖然在發(fā)生錯(cuò)誤時(shí),整個(gè)數(shù)據(jù)庫的狀態(tài)可以恢復(fù),但是如果我們?cè)谑聞?wù)中執(zhí)行了諸如:向標(biāo)準(zhǔn)輸出打印日志、向外界發(fā)出郵件、沒有通過數(shù)據(jù)庫修改了磁盤上的內(nèi)容甚至在事務(wù)執(zhí)行期間發(fā)生了轉(zhuǎn)賬匯款,那么這些操作作為可見的外部輸出都是沒有辦法回滾的;這些問題都是由應(yīng)用開發(fā)者解決和負(fù)責(zé)的,在絕大多數(shù)情況下,我們都需要在整個(gè)事務(wù)提交后,再觸發(fā)類似的無法回滾的操作

以訂票為例,哪怕我們?cè)谡麄€(gè)事務(wù)結(jié)束之后,才向第三方發(fā)起請(qǐng)求,由于向第三方請(qǐng)求并獲取結(jié)果是一個(gè)需要較長事件的操作,如果在事務(wù)剛剛提交時(shí),數(shù)據(jù)庫或者服務(wù)器發(fā)生了崩潰,那么我們就非常有可能丟失發(fā)起請(qǐng)求這一過程,這就造成了非常嚴(yán)重的問題;而這一點(diǎn)就不是數(shù)據(jù)庫所能保證的,開發(fā)者需要在適當(dāng)?shù)臅r(shí)候查看請(qǐng)求是否被發(fā)起、結(jié)果是成功還是失敗。

并行事務(wù)的原子性

到目前為止,所有的事務(wù)都只是串行執(zhí)行的,一直都沒有考慮過并行執(zhí)行的問題;然而在實(shí)際工作中,并行執(zhí)行的事務(wù)才是常態(tài),然而并行任務(wù)下,卻可能出現(xiàn)非常復(fù)雜的問題:

當(dāng) Transaction1 在執(zhí)行的過程中對(duì) id = 1 的用戶進(jìn)行了讀寫,但是沒有將修改的內(nèi)容進(jìn)行提交或者回滾,在這時(shí) Transaction2 對(duì)同樣的數(shù)據(jù)進(jìn)行了讀操作并提交了事務(wù);也就是說 Transaction2 是依賴于 Transaction1 的,當(dāng) Transaction1 由于一些錯(cuò)誤需要回滾時(shí),因?yàn)橐WC事務(wù)的原子性,需要對(duì) Transaction2 進(jìn)行回滾,但是由于我們已經(jīng)提交了 Transaction2,所以我們已經(jīng)沒有辦法進(jìn)行回滾操作,在這種問題下我們就發(fā)生了問題,Database System Concepts 一書中將這種現(xiàn)象稱為不可恢復(fù)安排(Nonrecoverable Schedule),那什么情況下是可以恢復(fù)的呢?

A recoverable schedule is one where, for each pair of transactions Ti and Tj such that Tj reads a data item previously written by Ti , the commit operation of Ti appears before the commit operation of Tj .

簡單理解一下,如果 Transaction2 依賴于事務(wù) Transaction1,那么事務(wù) Transaction1 必須在 Transaction2 提交之前完成提交的操作:

然而這樣還不算完,當(dāng)事務(wù)的數(shù)量逐漸增多時(shí),整個(gè)恢復(fù)流程也會(huì)變得越來越復(fù)雜,如果我們想要從事務(wù)發(fā)生的錯(cuò)誤中恢復(fù),也不是一件那么容易的事情。

在上圖所示的一次事件中,Transaction2 依賴于 Transaction1,而 Transaction3 又依賴于 Transaction1,當(dāng) Transaction1 由于執(zhí)行出現(xiàn)問題發(fā)生回滾時(shí),為了保證事務(wù)的原子性,就會(huì)將 Transaction2 和 Transaction3 中的工作全部回滾,這種情況也叫做級(jí)聯(lián)回滾(Cascading Rollback),級(jí)聯(lián)回滾的發(fā)生會(huì)導(dǎo)致大量的工作需要撤回,是我們難以接受的,不過如果想要達(dá)到絕對(duì)的原子性,這件事情又是不得不去處理的,我們會(huì)在文章的后面具體介紹如何處理并行事務(wù)的原子性。

持久性

既然是數(shù)據(jù)庫,那么一定對(duì)數(shù)據(jù)的持久存儲(chǔ)有著非常強(qiáng)烈的需求,如果數(shù)據(jù)被寫入到數(shù)據(jù)庫中,那么數(shù)據(jù)一定能夠被安全存儲(chǔ)在磁盤上;而事務(wù)的持久性就體現(xiàn)在,一旦事務(wù)被提交,那么數(shù)據(jù)一定會(huì)被寫入到數(shù)據(jù)庫中并持久存儲(chǔ)起來。

當(dāng)事務(wù)已經(jīng)被提交之后,就無法再次回滾了,唯一能夠撤回已經(jīng)提交的事務(wù)的方式就是創(chuàng)建一個(gè)相反的事務(wù)對(duì)原操作進(jìn)行『補(bǔ)償』,這也是事務(wù)持久性的體現(xiàn)之一。

重做日志

與原子性一樣,事務(wù)的持久性也是通過日志來實(shí)現(xiàn)的,MySQL 使用重做日志(redo log)實(shí)現(xiàn)事務(wù)的持久性,重做日志由兩部分組成,一是內(nèi)存中的重做日志緩沖區(qū),因?yàn)橹刈鋈罩揪彌_區(qū)在內(nèi)存中,所以它是易失的,另一個(gè)就是在磁盤上的重做日志文件,它是持久的

當(dāng)我們?cè)谝粋€(gè)事務(wù)中嘗試對(duì)數(shù)據(jù)進(jìn)行修改時(shí),它會(huì)先將數(shù)據(jù)從磁盤讀入內(nèi)存,并更新內(nèi)存中緩存的數(shù)據(jù),然后生成一條重做日志并寫入重做日志緩存,當(dāng)事務(wù)真正提交時(shí),MySQL 會(huì)將重做日志緩存中的內(nèi)容刷新到重做日志文件,再將內(nèi)存中的數(shù)據(jù)更新到磁盤上,圖中的第 4、5 步就是在事務(wù)提交時(shí)執(zhí)行的。

在 InnoDB 中,重做日志都是以 512 字節(jié)的塊的形式進(jìn)行存儲(chǔ)的,同時(shí)因?yàn)閴K的大小與磁盤扇區(qū)大小相同,所以重做日志的寫入可以保證原子性,不會(huì)由于機(jī)器斷電導(dǎo)致重做日志僅寫入一半并留下臟數(shù)據(jù)。

除了所有對(duì)數(shù)據(jù)庫的修改會(huì)產(chǎn)生重做日志,因?yàn)榛貪L日志也是需要持久存儲(chǔ)的,它們也會(huì)創(chuàng)建對(duì)應(yīng)的重做日志,在發(fā)生錯(cuò)誤后,數(shù)據(jù)庫重啟時(shí)會(huì)從重做日志中找出未被更新到數(shù)據(jù)庫磁盤中的日志重新執(zhí)行以滿足事務(wù)的持久性。

回滾日志和重做日志

到現(xiàn)在為止我們了解了 MySQL 中的兩種日志,回滾日志(undo log)和重做日志(redo log);在數(shù)據(jù)庫系統(tǒng)中,事務(wù)的原子性和持久性是由事務(wù)日志(transaction log)保證的,在實(shí)現(xiàn)時(shí)也就是上面提到的兩種日志,前者用于對(duì)事務(wù)的影響進(jìn)行撤銷,后者在錯(cuò)誤處理時(shí)對(duì)已經(jīng)提交的事務(wù)進(jìn)行重做,它們能保證兩點(diǎn):

發(fā)生錯(cuò)誤或者需要回滾的事務(wù)能夠成功回滾(原子性);

在事務(wù)提交后,數(shù)據(jù)沒來得及寫會(huì)磁盤就宕機(jī)時(shí),在下次重新啟動(dòng)后能夠成功恢復(fù)數(shù)據(jù)(持久性);

在數(shù)據(jù)庫中,這兩種日志經(jīng)常都是一起工作的,我們可以將它們整體看做一條事務(wù)日志,其中包含了事務(wù)的 ID、修改的行元素以及修改前后的值。

一條事務(wù)日志同時(shí)包含了修改前后的值,能夠非常簡單的進(jìn)行回滾和重做兩種操作,在這里我們也不會(huì)對(duì)重做和回滾日志展開進(jìn)行介紹,可能會(huì)在之后的文章談一談數(shù)據(jù)庫系統(tǒng)的恢復(fù)機(jī)制時(shí)提到兩種日志的使用。

隔離性

其實(shí)作者在之前的文章 『淺入淺出』MySQL 和 InnoDB 就已經(jīng)介紹過數(shù)據(jù)庫事務(wù)的隔離性,不過為了保證文章的獨(dú)立性和完整性,我們還會(huì)對(duì)事務(wù)的隔離性進(jìn)行介紹,介紹的內(nèi)容可能稍微有所不同。

事務(wù)的隔離性是數(shù)據(jù)庫處理數(shù)據(jù)的幾大基礎(chǔ)之一,如果沒有數(shù)據(jù)庫的事務(wù)之間沒有隔離性,就會(huì)發(fā)生在 并行事務(wù)的原子性 一節(jié)中提到的級(jí)聯(lián)回滾等問題,造成性能上的巨大損失。如果所有的事務(wù)的執(zhí)行順序都是線性的,那么對(duì)于事務(wù)的管理容易得多,但是允許事務(wù)的并行執(zhí)行卻能能夠提升吞吐量和資源利用率,并且可以減少每個(gè)事務(wù)的等待時(shí)間。

當(dāng)多個(gè)事務(wù)同時(shí)并發(fā)執(zhí)行時(shí),事務(wù)的隔離性可能就會(huì)被違反,雖然單個(gè)事務(wù)的執(zhí)行可能沒有任何錯(cuò)誤,但是從總體來看就會(huì)造成數(shù)據(jù)庫的一致性出現(xiàn)問題,而串行雖然能夠允許開發(fā)者忽略并行造成的影響,能夠很好地維護(hù)數(shù)據(jù)庫的一致性,但是卻會(huì)影響事務(wù)執(zhí)行的性能。

事務(wù)的隔離級(jí)別

所以說數(shù)據(jù)庫的隔離性和一致性其實(shí)是一個(gè)需要開發(fā)者去權(quán)衡的問題,為數(shù)據(jù)庫提供什么樣的隔離性層級(jí)也就決定了數(shù)據(jù)庫的性能以及可以達(dá)到什么樣的一致性;在 SQL 標(biāo)準(zhǔn)中定義了四種數(shù)據(jù)庫的事務(wù)的隔離級(jí)別:READ UNCOMMITED、READ COMMITED、REPEATABLE READ 和 SERIALIZABLE;每個(gè)事務(wù)的隔離級(jí)別其實(shí)都比上一級(jí)多解決了一個(gè)問題:

RAED UNCOMMITED:使用查詢語句不會(huì)加鎖,可能會(huì)讀到未提交的行(Dirty Read);

READ COMMITED:只對(duì)記錄加記錄鎖,而不會(huì)在記錄之間加間隙鎖,所以允許新的記錄插入到被鎖定記錄的附近,所以再多次使用查詢語句時(shí),可能得到不同的結(jié)果(Non-Repeatable Read);

REPEATABLE READ:多次讀取同一范圍的數(shù)據(jù)會(huì)返回第一次查詢的快照,不會(huì)返回不同的數(shù)據(jù)行,但是可能發(fā)生幻讀(Phantom Read);

SERIALIZABLE:InnoDB 隱式地將全部的查詢語句加上共享鎖,解決了幻讀的問題;

以上的所有的事務(wù)隔離級(jí)別都不允許臟寫入(Dirty Write),也就是當(dāng)前事務(wù)更新了另一個(gè)事務(wù)已經(jīng)更新但是還未提交的數(shù)據(jù),大部分的數(shù)據(jù)庫中都使用了 READ COMMITED 作為默認(rèn)的事務(wù)隔離級(jí)別,但是 MySQL 使用了 REPEATABLE READ 作為默認(rèn)配置;從 RAED UNCOMMITED 到 SERIALIZABLE,隨著事務(wù)隔離級(jí)別變得越來越嚴(yán)格,數(shù)據(jù)庫對(duì)于并發(fā)執(zhí)行事務(wù)的性能也逐漸下降。

對(duì)于數(shù)據(jù)庫的使用者,從理論上說,并不需要知道事務(wù)的隔離級(jí)別是如何實(shí)現(xiàn)的,我們只需要知道這個(gè)隔離級(jí)別解決了什么樣的問題,但是不同數(shù)據(jù)庫對(duì)于不同隔離級(jí)別的是實(shí)現(xiàn)細(xì)節(jié)在很多時(shí)候都會(huì)讓我們遇到意料之外的坑。

如果讀者不了解臟讀、不可重復(fù)讀和幻讀究竟是什么,可以閱讀之前的文章 『淺入淺出』MySQL 和 InnoDB,在這里我們僅放一張圖來展示各個(gè)隔離層級(jí)對(duì)這幾個(gè)問題的解決情況。

隔離級(jí)別的實(shí)現(xiàn)

數(shù)據(jù)庫對(duì)于隔離級(jí)別的實(shí)現(xiàn)就是使用并發(fā)控制機(jī)制對(duì)在同一時(shí)間執(zhí)行的事務(wù)進(jìn)行控制,限制不同的事務(wù)對(duì)于同一資源的訪問和更新,而最重要也最常見的并發(fā)控制機(jī)制,在這里我們將簡單介紹三種最重要的并發(fā)控制器機(jī)制的工作原理。

鎖是一種最為常見的并發(fā)控制機(jī)制,在一個(gè)事務(wù)中,我們并不會(huì)將整個(gè)數(shù)據(jù)庫都加鎖,而是只會(huì)鎖住那些需要訪問的數(shù)據(jù)項(xiàng), MySQL 和常見數(shù)據(jù)庫中的鎖都分為兩種,共享鎖(Shared)和互斥鎖(Exclusive),前者也叫讀鎖,后者叫寫鎖。

讀鎖保證了讀操作可以并發(fā)執(zhí)行,相互不會(huì)影響,而寫鎖保證了在更新數(shù)據(jù)庫數(shù)據(jù)時(shí)不會(huì)有其他的事務(wù)訪問或者更改同一條記錄造成不可預(yù)知的問題。

時(shí)間戳

除了鎖,另一種實(shí)現(xiàn)事務(wù)的隔離性的方式就是通過時(shí)間戳,使用這種方式實(shí)現(xiàn)事務(wù)的數(shù)據(jù)庫,例如 PostgreSQL 會(huì)為每一條記錄保留兩個(gè)字段;讀時(shí)間戳中報(bào)錯(cuò)了所有訪問該記錄的事務(wù)中的最大時(shí)間戳,而記錄行的寫時(shí)間戳中保存了將記錄改到當(dāng)前值的事務(wù)的時(shí)間戳。

使用時(shí)間戳實(shí)現(xiàn)事務(wù)的隔離性時(shí),往往都會(huì)使用樂觀鎖,先對(duì)數(shù)據(jù)進(jìn)行修改,在寫回時(shí)再去判斷當(dāng)前值,也就是時(shí)間戳是否改變過,如果沒有改變過,就寫入,否則,生成一個(gè)新的時(shí)間戳并再次更新數(shù)據(jù),樂觀鎖其實(shí)并不是真正的鎖機(jī)制,它只是一種思想,在這里并不會(huì)對(duì)它進(jìn)行展開介紹。

多版本和快照隔離

通過維護(hù)多個(gè)版本的數(shù)據(jù),數(shù)據(jù)庫可以允許事務(wù)在數(shù)據(jù)被其他事務(wù)更新時(shí)對(duì)舊版本的數(shù)據(jù)進(jìn)行讀取,很多數(shù)據(jù)庫都對(duì)這一機(jī)制進(jìn)行了實(shí)現(xiàn);因?yàn)樗械淖x操作不再需要等待寫鎖的釋放,所以能夠顯著地提升讀的性能,MySQL 和 PostgreSQL 都對(duì)這一機(jī)制進(jìn)行自己的實(shí)現(xiàn),也就是 MVCC,雖然各自實(shí)現(xiàn)的方式有所不同,MySQL 就通過文章中提到的回滾日志實(shí)現(xiàn)了 MVCC,保證事務(wù)并行執(zhí)行時(shí)能夠不等待互斥鎖的釋放直接獲取數(shù)據(jù)。

隔離性與原子性

在這里就需要簡單提一下在在原子性一節(jié)中遇到的級(jí)聯(lián)回滾等問題了,如果一個(gè)事務(wù)對(duì)數(shù)據(jù)進(jìn)行了寫入,這時(shí)就會(huì)獲取一個(gè)互斥鎖,其他的事務(wù)就想要獲得改行數(shù)據(jù)的讀鎖就必須等待寫鎖的釋放,自然就不會(huì)發(fā)生級(jí)聯(lián)回滾等問題了。

不過在大多數(shù)的數(shù)據(jù)庫,比如 MySQL 中都使用了 MVCC 等特性,也就是正常的讀方法是不需要獲取鎖的,在想要對(duì)讀取的數(shù)據(jù)進(jìn)行更新時(shí)需要使用 SELECT ... FOR UPDATE 嘗試獲取對(duì)應(yīng)行的互斥鎖,以保證不同事務(wù)可以正常工作。

一致性

作者認(rèn)為數(shù)據(jù)庫的一致性是一個(gè)非常讓人迷惑的概念,原因是數(shù)據(jù)庫領(lǐng)域其實(shí)包含兩個(gè)一致性,一個(gè)是 ACID 中的一致性、另一個(gè)是 CAP 定義中的一致性。

這兩個(gè)數(shù)據(jù)庫的一致性說的完全不是一個(gè)事情,很多很多人都對(duì)這兩者的概念有非常深的誤解,當(dāng)我們?cè)谟懻摂?shù)據(jù)庫的一致性時(shí),一定要清楚上下文的語義是什么,盡量明確的問出我們要討論的到底是 ACID 中的一致性還是 CAP 中的一致性。

ACID

數(shù)據(jù)庫對(duì)于 ACID 中的一致性的定義是這樣的:如果一個(gè)事務(wù)原子地在一個(gè)一致地?cái)?shù)據(jù)庫中獨(dú)立運(yùn)行,那么在它執(zhí)行之后,數(shù)據(jù)庫的狀態(tài)一定是一致的。對(duì)于這個(gè)概念,它的第一層意思就是對(duì)于數(shù)據(jù)完整性的約束,包括主鍵約束、引用約束以及一些約束檢查等等,在事務(wù)的執(zhí)行的前后以及過程中不會(huì)違背對(duì)數(shù)據(jù)完整性的約束,所有對(duì)數(shù)據(jù)庫寫入的操作都應(yīng)該是合法的,并不能產(chǎn)生不合法的數(shù)據(jù)狀態(tài)。

A transaction must preserve database consistency - if a transaction is run atomically in isolation starting from a consistent database, the database must again be consistent at the end of the transaction.

我們可以將事務(wù)理解成一個(gè)函數(shù),它接受一個(gè)外界的 SQL 輸入和一個(gè)一致的數(shù)據(jù)庫,它一定會(huì)返回一個(gè)一致的數(shù)據(jù)庫。

而第二層意思其實(shí)是指邏輯上的對(duì)于開發(fā)者的要求,我們要在代碼中寫出正確的事務(wù)邏輯,比如銀行轉(zhuǎn)賬,事務(wù)中的邏輯不可能只扣錢或者只加錢,這是應(yīng)用層面上對(duì)于數(shù)據(jù)庫一致性的要求。

Ensuring consistency for an individual transaction is the responsibility of the application programmer who codes the transaction. - Database System Concepts

數(shù)據(jù)庫 ACID 中的一致性對(duì)事務(wù)的要求不止包含對(duì)數(shù)據(jù)完整性以及合法性的檢查,還包含應(yīng)用層面邏輯的正確。

CAP 定理中的數(shù)據(jù)一致性,其實(shí)是說分布式系統(tǒng)中的各個(gè)節(jié)點(diǎn)中對(duì)于同一數(shù)據(jù)的拷貝有著相同的值;而 ACID 中的一致性是指數(shù)據(jù)庫的規(guī)則,如果 schema 中規(guī)定了一個(gè)值必須是唯一的,那么一致的系統(tǒng)必須確保在所有的操作中,該值都是唯一的,由此來看 CAP 和 ACID 對(duì)于一致性的定義有著根本性的區(qū)別。

關(guān)于MySQL中什么是事務(wù)與鎖就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

網(wǎng)頁名稱:MySQL中什么是事務(wù)與鎖
分享路徑:http://www.chinadenli.net/article40/pigeho.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃企業(yè)建站用戶體驗(yàn)網(wǎng)站設(shè)計(jì)小程序開發(fā)虛擬主機(jī)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司