您好,登錄后才能下訂單哦!
這篇文章主要介紹PostgreSQL中什么是事務(wù),文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
一、什么是事務(wù)?
事務(wù)可以看作是一個(gè)操作的有序集,這些操作應(yīng)作為整體來(lái)對(duì)待,即集內(nèi)所有的操作都成功的時(shí)候,該事務(wù)才被認(rèn)為是成功的,否則的話,即使其中只有一個(gè)操作失敗,該事務(wù)也會(huì)被認(rèn)為是不成功。如果所有的操作全部成功,那么事務(wù)就會(huì)被提交,這時(shí)它的所作的修改才能被所有其他數(shù)據(jù)庫(kù)進(jìn)程所用。如果操作失敗,該事務(wù)就會(huì)被回滾,同時(shí)事務(wù)內(nèi)部所有已完成操作所做的修改會(huì)被全部撤銷。在事務(wù)提交之前,一次事務(wù)期間所作的修改,只對(duì)擁有此事務(wù)的進(jìn)程可用。之所以這樣做,是為了防止其他線程使用了事務(wù)修改的數(shù)據(jù)后,事務(wù)隨后又發(fā)生了回滾,從而導(dǎo)致數(shù)據(jù)完整性錯(cuò)誤。
事務(wù)功能是企業(yè)數(shù)據(jù)庫(kù)的關(guān)鍵所在,因?yàn)樵S多業(yè)務(wù)流程是由多步組成的,下面我們以在線購(gòu)物為例進(jìn)行說(shuō)明。在結(jié)帳時(shí),顧客的購(gòu)物車會(huì)跟現(xiàn)有庫(kù)存進(jìn)行比對(duì),以確保有現(xiàn)貨。接下來(lái),顧客必須提供收費(fèi)與交貨信息,這時(shí)就需要檢查相應(yīng)的信用卡是否可用,并從中扣款。然后,需要從產(chǎn)品庫(kù)存清單中扣除相應(yīng)的數(shù)量,如果庫(kù)存不足,還應(yīng)向采購(gòu)部門(mén)發(fā)出通知。在這些步驟中,只要有一步發(fā)生錯(cuò)誤,那么所有修改都不應(yīng)該生效。假設(shè)沒(méi)有現(xiàn)貨的情況下,還是從顧客的信用卡中扣了款的話,那么顧客會(huì)很生氣,問(wèn)題就會(huì)很嚴(yán)重了。同樣地,作為在線商家,當(dāng)信用卡無(wú)效的時(shí)候,您也肯定不希望從存貨清單中扣除此次顧客選擇的商品數(shù)量,或者因此而發(fā)出相應(yīng)的采購(gòu)?fù)ㄖ?/p>
我們這里所說(shuō)的事務(wù),必須滿足四大要件:
l 原子性:事務(wù)所有的步驟必須全部成功;否則,任何步驟都不會(huì)被提交。
l 一致性:事務(wù)所有的步驟必須全部成功;否則,所有的數(shù)據(jù)都會(huì)恢復(fù)到事務(wù)開(kāi)始之前的狀態(tài)。
l 隔離性:在事務(wù)完成之前,所有已執(zhí)行的步驟必須與系統(tǒng)保持隔離。
l 持久性:所有提交的數(shù)據(jù),系統(tǒng)必須加以恰當(dāng)保存,并保證萬(wàn)一系統(tǒng)發(fā)生故障時(shí)仍能將數(shù)據(jù)恢復(fù)到有效狀態(tài)。
PostgreSQL的事務(wù)支持功能完全遵循上述四項(xiàng)基本原則(有時(shí)候人們簡(jiǎn)稱為ACID),從而能夠有效保證數(shù)據(jù)庫(kù)的完整性。
二、PostgreSQL的事務(wù)隔離
PostgreSQL的事務(wù)支持是通過(guò)通常所說(shuō)的多版本并發(fā)控制或者M(jìn)VCC方法實(shí)現(xiàn)的,也就是說(shuō),每當(dāng)事務(wù)進(jìn)行處理時(shí),它看到的是自己的數(shù)據(jù)庫(kù)快照,而非底層數(shù)據(jù)的實(shí)際狀態(tài)。 這使得任何給定的事務(wù)無(wú)法看到其它已經(jīng)啟動(dòng)但是尚未提交的事務(wù)對(duì)數(shù)據(jù)所作的部分修改。這項(xiàng)原則就是所謂的事務(wù)隔離。
SQL標(biāo)準(zhǔn)規(guī)定了三種屬性以用來(lái)確定一個(gè)事務(wù)處于四級(jí)隔離級(jí)別的哪一級(jí),這些屬性如下所示:
l 臟讀:一個(gè)事務(wù)讀取了另一個(gè)未提交的并行事務(wù)寫(xiě)的數(shù)據(jù)
l 不可重復(fù)讀:當(dāng)一個(gè)事務(wù)重新讀取前面讀取過(guò)的數(shù)據(jù)時(shí),發(fā)現(xiàn)該數(shù)據(jù)已經(jīng)被另一個(gè)已提交的事務(wù)修改過(guò)
l 幻讀:一個(gè)事務(wù)重新執(zhí)行一個(gè)查詢時(shí),返回一套符合查詢條件的行,發(fā)現(xiàn)這些行因?yàn)槠渌罱峤坏氖聞?wù)而發(fā)生了改變
這三種情況確定了一個(gè)事務(wù)的隔離級(jí)別,所有四種水平如表1所示。
表1 SQL標(biāo)準(zhǔn)事務(wù)隔離級(jí)別
#FormatImgID_0#
PostgreSQL允許您請(qǐng)求四種可能的事務(wù)隔離級(jí)別中的任意一種。但是在內(nèi)部,實(shí)際上只有兩種可用的隔離級(jí)別,分別對(duì)應(yīng)讀已提交和可串行化。如果你選擇了讀未提交的級(jí)別,實(shí)際上你用的是讀已提交,在你選擇可重復(fù)的讀級(jí)別的時(shí)候,實(shí)際上你用的是可串行化,所以實(shí)際的隔離級(jí)別可能比你選擇的更嚴(yán)格。雖然這看起來(lái)是有悖于我們的直覺(jué),但是SQL標(biāo)準(zhǔn)的確允許這樣做,因?yàn)樗姆N隔離級(jí)別只定義了哪種現(xiàn)象不能發(fā)生,但是沒(méi)有定義那種現(xiàn)象一定發(fā)生,所以除了不允許的事務(wù)特性之外,所有的特性都是允許的。舉例來(lái)說(shuō),如果您請(qǐng)求可重復(fù)讀模式,那么該標(biāo)準(zhǔn)只是要求您不準(zhǔn)臟讀以及不可重讀,但是卻沒(méi)有要求允許幻讀。因此,可串行化事務(wù)模式滿足可重復(fù)讀模式的要求,即使它跟定義沒(méi)有完全吻合。因此,您應(yīng)當(dāng)確切的知道,當(dāng)您請(qǐng)求讀未提交模式的時(shí)候,您實(shí)際得到的卻是讀已提交模式;而當(dāng)您請(qǐng)求可重復(fù)讀的時(shí)候,實(shí)際得到的是可串行化模式。您還應(yīng)當(dāng)意識(shí)到,默認(rèn)情況下,如果您沒(méi)有請(qǐng)求一個(gè)特定的隔離級(jí)別,那么您得到的將是讀已提交隔離級(jí)別。
下面我們了解一下讀已提交和可串行化之間的主要區(qū)別。在讀已提交模式下SELECT 查詢只能看到該查詢開(kāi)始之前提交的數(shù)據(jù)而永遠(yuǎn)無(wú)法看到未提交的數(shù)據(jù)或者是在查詢執(zhí)行時(shí)其他并行的事務(wù)提交的改變;不過(guò) SELECT 的確看得見(jiàn)同一次事務(wù)中前面更新的結(jié)果,即使它們還沒(méi)提交也看得到。實(shí)際上,一個(gè) SELECT 查詢看到一個(gè)在該查詢開(kāi)始運(yùn)行的瞬間該數(shù)據(jù)庫(kù)的一個(gè)快照。請(qǐng)注意兩個(gè)相鄰的 SELECT 命令可能看到不同的數(shù)據(jù),哪怕它們是在同一個(gè)事務(wù)里,因?yàn)槠渌聞?wù)會(huì)在第一個(gè)SELECT執(zhí)行的時(shí)候提交。當(dāng)一個(gè)事務(wù)處于可串行化級(jí)別的時(shí)候,一個(gè) SELECT 查詢只能看到在該事務(wù)開(kāi)始之前提交的數(shù)據(jù)而永遠(yuǎn)看不到未提交的數(shù)據(jù)或事務(wù)執(zhí)行中其他并行事務(wù)提交的修改;不過(guò),SELECT 的確看得到同一次事務(wù)中前面的更新的效果,即使事務(wù)還沒(méi)有提交也一樣。這個(gè)行為和讀已提交級(jí)別是不太一樣,它的 SELECT 看到的是該事務(wù)開(kāi)始時(shí)的快照,而不是該事務(wù)內(nèi)部當(dāng)前查詢開(kāi)始時(shí)的快照。這樣,一個(gè)事務(wù)內(nèi)部后面的SELECT命令總是看到同樣的數(shù)據(jù)。這意味著,讀已提交模式下一個(gè)事務(wù)內(nèi)部后面的SELECT命令可以看到不同的數(shù)據(jù),但是在可串行化模式下卻總是看到同樣的數(shù)據(jù)。
對(duì)于以上區(qū)別,請(qǐng)讀者一定弄清楚。雖然剛看上去有些復(fù)雜,但是只要抓住兩個(gè)要點(diǎn),理解起來(lái)還是很容易的:首先,PostgreSQL運(yùn)行事務(wù)的并發(fā)運(yùn)行,也就是說(shuō)一個(gè)事務(wù)執(zhí)行的時(shí)候,并不妨礙另一事務(wù)對(duì)相同數(shù)據(jù)操作。其次,一定注意快照的概念,事務(wù)提交前操作的是數(shù)據(jù)快照而非數(shù)據(jù)庫(kù)本身,同時(shí)注意不同隔離級(jí)別使用的是何時(shí)的快照——事務(wù)開(kāi)始之前的快照,還是事務(wù)內(nèi)部操作開(kāi)始之前的快照?我想只要抓住了以上要點(diǎn),我們就能很好的把握各種隔離級(jí)別之間的區(qū)別了。
上面介紹了事務(wù)的基本概念,接下來(lái)我們開(kāi)始演示如何在PostgreSQL客戶端中使用事務(wù)。
三、創(chuàng)建示例表
下面,我們通過(guò)一個(gè)具體的在線交易應(yīng)用為例來(lái)闡述上面介紹的事務(wù)概念。為此,我們需要先給這個(gè)示例程序在名為company的數(shù)據(jù)庫(kù)中創(chuàng)建兩個(gè)表:participant和trunk。同時(shí),我們還會(huì)介紹各個(gè)表的用途和結(jié)構(gòu)。建好表后,我們還需為它們填入一些樣本數(shù)據(jù),具體如下所示。
我們首先創(chuàng)建Participant表,這個(gè)表用來(lái)存放參與物品交換者的信息,包括他們的姓名、電子郵件地址和可用現(xiàn)金:
1 CREATE TABLE participant (
2 participantid SERIAL,
3 name TEXT NOT NULL,
4 email TEXT NOT NULL,
5 cash NUMERIC(5,2) NOT NULL,
6 PRIMARY KEY (participantid)
7 );
8 CREATE TABLE<span
以上是“PostgreSQL中什么是事務(wù)”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。