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

讓我們一起了解事務(wù)之ACID

開(kāi)發(fā) 架構(gòu)
隨著科技的飛速發(fā)展,人類社會(huì)也邁入了大數(shù)據(jù)時(shí)代。很多數(shù)據(jù)的值不準(zhǔn)對(duì)我們的生活影響不會(huì)很大,比如手表記錄下來(lái)的我今天走路步數(shù)是10000步,實(shí)際就算記成了9500步對(duì)我來(lái)講也不會(huì)太關(guān)心。

[[437157]]

本文轉(zhuǎn)載自微信公眾號(hào)「程序員阿sir」,作者程序員阿sir。轉(zhuǎn)載本文請(qǐng)聯(lián)系程序員阿sir公眾號(hào)。

隨著科技的飛速發(fā)展,人類社會(huì)也邁入了大數(shù)據(jù)時(shí)代。很多數(shù)據(jù)的值不準(zhǔn)對(duì)我們的生活影響不會(huì)很大,比如手表記錄下來(lái)的我今天走路步數(shù)是10000步,實(shí)際就算記成了9500步對(duì)我來(lái)講也不會(huì)太關(guān)心。但是有些數(shù)據(jù)就分毫不能差,比如銀行卡里的錢不能莫名其妙的就少了500塊錢。所有的數(shù)據(jù)肯定都需要存在在一些數(shù)據(jù)系統(tǒng)里面,比如數(shù)據(jù)庫(kù),硬盤,云存儲(chǔ)等等。但是現(xiàn)在的應(yīng)用越來(lái)越復(fù)雜,在訪問(wèn)數(shù)據(jù)系統(tǒng)經(jīng)常出現(xiàn)各種問(wèn)題,比如:

  • 寫數(shù)據(jù)到數(shù)據(jù)庫(kù)的時(shí)候出現(xiàn)了軟件或硬件故障導(dǎo)致數(shù)據(jù)寫了一半失敗了;
  • 應(yīng)用突然崩了;
  • 網(wǎng)絡(luò)突然斷了導(dǎo)致應(yīng)用連接不上數(shù)據(jù)庫(kù)了;
  • 多個(gè)客戶端想要同時(shí)更新同一個(gè)值導(dǎo)致后者覆蓋了前者。

比如小明想給小華轉(zhuǎn)賬100塊錢,銀行應(yīng)用的業(yè)務(wù)邏輯是如果小明賬號(hào)里的余額大于100元時(shí),會(huì)從小明的賬號(hào)里減去100元,然后把小華的賬號(hào)余額加上100元。但是如果剛從小明的賬號(hào)里扣除100元時(shí),銀行網(wǎng)斷了導(dǎo)致后面給小華的錢沒(méi)加成功,這樣就出現(xiàn)了重大問(wèn)題,在銀行轉(zhuǎn)賬時(shí)絕對(duì)不能發(fā)生。所以銀行的應(yīng)用開(kāi)發(fā)時(shí)需要考慮這種異常并進(jìn)行處理,比如等來(lái)網(wǎng)了的時(shí)候把小華的賬號(hào)里加上100塊錢。

我們可以在應(yīng)用端處理各種異常,讓應(yīng)用變得更加魯棒,但是其中這里面有很多細(xì)節(jié)的問(wèn)題需要考慮,非常麻煩。而事務(wù) ( Transaction ) 是一種可以簡(jiǎn)化問(wèn)題的機(jī)制。

1. 什么是事務(wù)

事務(wù)可以把一個(gè)應(yīng)用的多個(gè)讀寫操作合并為一個(gè)邏輯單元。理論來(lái)說(shuō),一個(gè)事務(wù)中的所有讀寫操作執(zhí)行的時(shí)候就像是一個(gè)操作一樣:或者整個(gè)事務(wù)的所有操作成功,或者整個(gè)事務(wù)的所有操作全部失敗。 不允許出現(xiàn)在一個(gè)事務(wù)中:其中的一部分操作成功了,但是另一部分的操作失敗了的情況。這樣就簡(jiǎn)化了問(wèn)題。比如上面的例子中,把扣除小明賬號(hào)的錢和增加小華賬號(hào)里的錢看作一個(gè)事務(wù),那中間網(wǎng)斷了最多就是沒(méi)轉(zhuǎn)帳成功,兩邊的錢都沒(méi)變化,這就保證了不會(huì)存在錢轉(zhuǎn)丟了的情況。這樣也方便應(yīng)用進(jìn)行重試 ( Safely Retry )。

大家可能之前都聽(tīng)說(shuō)過(guò)或用到過(guò)事務(wù),看上去好像數(shù)據(jù)庫(kù)就應(yīng)該使用事務(wù)。但是事務(wù)并不是本來(lái)就天然存在的,他是為了簡(jiǎn)化訪問(wèn)數(shù)據(jù)庫(kù)時(shí)的編程模型而被創(chuàng)造出來(lái)的概念。使用事務(wù)可以幫助開(kāi)發(fā)者忽略一些潛在的數(shù)據(jù)問(wèn)題和并發(fā)問(wèn)題,因?yàn)閷?shí)現(xiàn)事務(wù)的數(shù)據(jù)庫(kù)本身會(huì)幫忙處理這類問(wèn)題。

那既然事務(wù)這么好,是不是所有數(shù)據(jù)庫(kù)都實(shí)現(xiàn)了事務(wù),我們就直接用就行,不需要了解事務(wù)的具體原理了。實(shí)際不是的。因?yàn)槭聞?wù)的實(shí)現(xiàn)有很多種方式以及不同的級(jí)別,他們對(duì)應(yīng)用性能的影響也是不同的。比如一種事務(wù)隔離性的實(shí)現(xiàn)方式就是加鎖,我們把一個(gè)事務(wù)里涉及的所有數(shù)據(jù)行都加上鎖,這樣別的事務(wù)根本不能讀寫我們鎖下的這些行數(shù)據(jù),直到事務(wù)結(jié)束才釋放這些鎖,這樣肯定就能避免數(shù)據(jù)不一致的情況了。但是這樣相當(dāng)于把讀寫數(shù)據(jù)串行化了,會(huì)非常影響性能。銀行數(shù)據(jù)非常重要,這樣實(shí)現(xiàn)雖然慢但是保證數(shù)據(jù)的安全了也還能接受。但是假設(shè)我們的應(yīng)用中數(shù)據(jù)沒(méi)有那么重要的情況下,可能我們這種拿性能換數(shù)據(jù)一致的做法就不太合理了。因此不是每個(gè)應(yīng)用都需要事務(wù)。

盡管事務(wù)看上去簡(jiǎn)單直接,但是實(shí)際有很多細(xì)節(jié)需要考慮情況,我們將會(huì)一一進(jìn)行介紹。首先先介紹一下數(shù)據(jù)庫(kù)中 ACID 的概念。

2. 什么是 ACID

事務(wù)提供的安全保證 ( Safety Guarantee )可以用 ACID 來(lái)描述分別是:

  • 原子性 ( Atomicity )
  • 一致性 ( Consistency )
  • 隔離性 ( Isolation)
  • 持久性 (Durability )。

這是一些事務(wù)的安全保證,但是不同數(shù)據(jù)庫(kù)對(duì)于ACID的實(shí)現(xiàn)可能也是不同的。比如對(duì)于隔離性就存在巨大的歧義。所以今天一個(gè)數(shù)據(jù)庫(kù)說(shuō)自己滿足ACID要求,但是可能和你以為的ACID并不一樣。下面分別對(duì)這四種安全保證進(jìn)行解釋。

2.1. 原子性 ( Atomicity )

原子這個(gè)詞很容易造成誤解。大家很容易聯(lián)想到多線程中的原子操作。如果一個(gè)線程執(zhí)行原子操作,表示其他線程不能看到這個(gè)原子操作的中間結(jié)果。

但是在 ACID 中,原子性和并發(fā)無(wú)關(guān),也就是說(shuō) ACID 中的原子性不表示當(dāng)多個(gè)進(jìn)程想要在同一時(shí)刻訪問(wèn)同一數(shù)據(jù)時(shí)會(huì)發(fā)生什么,但是隔離性表示的是這個(gè)意思。

ACID 中的原子性描述了如果一個(gè)事務(wù)中間出現(xiàn)了錯(cuò)誤(比如網(wǎng)絡(luò)突然斷了)導(dǎo)致這個(gè)事務(wù)不可能完成,那么事務(wù)必須回滾到事務(wù)開(kāi)始之前的狀態(tài)。 也就是說(shuō)刪掉這個(gè)事務(wù)已經(jīng)寫到數(shù)據(jù)庫(kù)中的修改。

原子性保證了事務(wù)中的操作要么全都發(fā)生,要么全都不發(fā)生,不可能一半完成了,一半沒(méi)做。其實(shí)回滾性 (Abortability) 這個(gè)名字比原子性更能表示這個(gè)特征,但是原子性還是更通用的一個(gè)叫法。

舉例來(lái)說(shuō),小明要給小華轉(zhuǎn)賬100元。事務(wù)里包含兩個(gè)操作,第一個(gè)是從小明的賬號(hào)里扣除100元,第二個(gè)是在小華的賬號(hào)里增加100元。原子性保證這個(gè)事務(wù)要么操作全成功,要么操作全失敗,不能出現(xiàn)小明的賬戶里少了100元,小華的賬號(hào)里錢數(shù)沒(méi)變。

2.2. 一致性 (Consistency)

ACID 中的一致性限制了我們自定義的一些數(shù)據(jù)約束永遠(yuǎn)為真。 比如上面銀行轉(zhuǎn)賬的例子,銀行定義的一個(gè)約束條件是無(wú)論怎么轉(zhuǎn)賬,大家的存款總額不變。

但是一致性實(shí)際取決于應(yīng)用本身的定義,也就是說(shuō)應(yīng)用負(fù)責(zé)定義哪些東西需要保持一致性。比如應(yīng)用邏輯就是要求扣小明100然后給小華賬號(hào)加200塊,數(shù)據(jù)庫(kù)也不能阻止他這樣做,因?yàn)檫@個(gè)是應(yīng)用里面定義的。數(shù)據(jù)庫(kù)可能可以加一些外鍵約束或者唯一性約束,但是一般來(lái)講,應(yīng)用負(fù)責(zé)定義什么數(shù)據(jù)是合理的,什么是不合理的,數(shù)據(jù)庫(kù)只負(fù)責(zé)存儲(chǔ)。

有意思的一點(diǎn)是:原子性、隔離性、持久性都是數(shù)據(jù)庫(kù)的性質(zhì),而一致性是應(yīng)用的性質(zhì)。應(yīng)用需要依數(shù)據(jù)庫(kù)的原子性和隔離性來(lái)實(shí)現(xiàn)一致性。所以從某種意義來(lái)說(shuō),ACID 中的 C 不應(yīng)該屬于數(shù)據(jù)庫(kù)的安全性保證范疇。

2.3. 隔離性

一個(gè)數(shù)據(jù)庫(kù)可以被多個(gè)客戶端訪問(wèn),如果他們想要讀寫數(shù)據(jù)庫(kù)的不同部分肯定沒(méi)有問(wèn)題,但是如果他們想要同時(shí)訪問(wèn)數(shù)據(jù)庫(kù)的同一條記錄,就有可能產(chǎn)生并發(fā)問(wèn)題 ( Concurrency Problem),也叫競(jìng)爭(zhēng)條件 (Race Conditions)。

比如下面的例子:

用戶1和用戶2都想增加數(shù)據(jù)庫(kù)中 counter 的值。在修改之前是42。用戶1讀到值為42,在用戶1改變 counter 的值之前,用戶2也讀到了當(dāng)前值為42,然后用戶1和用戶2分別在原始值上加1,得到43,然后寫入了數(shù)據(jù)庫(kù)。最終數(shù)據(jù)庫(kù)中 counter 的值變成了43,但實(shí)際正確的值應(yīng)該是44。

隔離性要解決的就是這個(gè)并發(fā)問(wèn)題。隔離性意思是并發(fā)執(zhí)行的事務(wù)之前彼此相互隔離,不應(yīng)該相互影響。

隔離性是 ACID 中最復(fù)雜的,也存在著很多概念上的爭(zhēng)議。大家可能認(rèn)為隔離性就是可串行化 (Serializability)。意思是數(shù)據(jù)庫(kù)需要保證這些事務(wù)在并發(fā)情況下運(yùn)行最后的結(jié)果需要和串行運(yùn)行這些事務(wù)的結(jié)果一致。實(shí)際上這確實(shí)是一種隔離性的實(shí)現(xiàn)方案,也是最高的隔離級(jí)別。但是這種實(shí)現(xiàn)卻很少會(huì)被用到,因?yàn)檫@會(huì)導(dǎo)致性能嚴(yán)重受到影響。有些數(shù)據(jù)庫(kù)甚至根本沒(méi)有實(shí)現(xiàn)這種方案,比如Oracle。Oracle 中有一種隔離級(jí)別是“可串行的” (Serializable),但是他實(shí)現(xiàn)的是一種較弱的隔離級(jí)別--快照隔離 (Snapshot Isolation),有種掛羊頭賣狗肉的感覺(jué)... 各種隔離級(jí)別的區(qū)分我們會(huì)在下一篇文章中介紹。

2.4. 持久性

持久性承諾一旦一個(gè)事務(wù)被成功完成,所有的數(shù)據(jù)改動(dòng)將不會(huì)回滾。即使硬盤壞了也能保證數(shù)據(jù)可以被持久存儲(chǔ)。

實(shí)際上沒(méi)有任何技術(shù)可以保證數(shù)據(jù)絕對(duì)持久保存。大家都只是用一些減少數(shù)據(jù)丟失的技術(shù),比如寫到硬盤、備份等等。

總結(jié)

這篇文章介紹了什么是事務(wù)以及數(shù)據(jù)庫(kù)安全保證中的 ACID 的含義。下一篇文章將繼續(xù)介紹事務(wù)的更多細(xì)節(jié)。

參考文獻(xiàn)

[1] Kleppmann, Martin. Designing data-intensive applications: The big ideas behind reliable, scalable, and maintainable systems. " O'Reilly Media, Inc.", 2017.

 

責(zé)任編輯:武曉燕 來(lái)源: 程序員阿sir
相關(guān)推薦

2021-07-14 08:00:12

Numa架構(gòu)Linux

2024-05-28 00:00:03

Java垃圾收集機(jī)制

2021-07-27 18:03:59

iOSSwift調(diào)度器

2021-10-27 07:15:37

SpringAOP編程(

2022-05-07 07:43:07

Redis存儲(chǔ)系統(tǒng)數(shù)據(jù)庫(kù)

2021-12-29 08:27:05

ByteBuffer磁盤服務(wù)器

2021-08-27 07:06:10

IOJava抽象

2022-03-08 17:52:58

TCP格式IP

2022-03-31 18:59:43

數(shù)據(jù)庫(kù)InnoDBMySQL

2023-06-30 08:27:20

2022-02-14 07:03:31

網(wǎng)站安全MFA

2022-06-26 09:40:55

Django框架服務(wù)

2016-09-06 10:39:30

Dell Techno

2022-02-14 10:16:22

Axios接口HTTP

2021-07-15 07:23:28

Singlefligh設(shè)計(jì)

2021-11-26 07:00:05

反轉(zhuǎn)整數(shù)數(shù)字

2023-08-14 08:38:26

反射reflect結(jié)構(gòu)體

2012-04-14 20:47:45

Android

2021-07-31 11:40:55

Openresty開(kāi)源

2021-12-16 12:01:21

區(qū)塊鏈Libra貨幣
點(diǎn)贊
收藏

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