W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
對于使用讀已提交事務(wù)的數(shù)據(jù)完整性強制業(yè)務(wù)規(guī)則非常困難,因為對每一個語句數(shù)據(jù)視圖都在變化,并且如果一個寫沖突發(fā)生即使一個單一語句也不能把它自己限制到該語句的快照。
雖然一個可重復讀事務(wù)在其執(zhí)行期間有一個穩(wěn)定的數(shù)據(jù)視圖,在使用MVCC快照進行數(shù)據(jù)一致性檢查時也有一個小問題,它涉及到被稱為讀/寫沖突的東西。如果一個事務(wù)寫數(shù)據(jù)并且一個并發(fā)事務(wù)嘗試讀相同的數(shù)據(jù)(不管是在寫之前還是之后),它不能看到其他事務(wù)的工作。讀取事務(wù)看起來是第一個執(zhí)行的,不管哪個是第一個啟動或者哪個是第一個提交。如果就到此為止,則沒有問題,但是如果讀取者也寫入被一個并發(fā)事務(wù)讀取的數(shù)據(jù),現(xiàn)在有一個事務(wù)好像是已經(jīng)在前面提到的任何一個事務(wù)之前運行。如果看起來最后執(zhí)行的事務(wù)實際上第一個提交,在這些事務(wù)的執(zhí)行順序圖中很容易出現(xiàn)一個環(huán)。當這樣一個環(huán)出現(xiàn)時,完整性檢查在沒有任何幫助的情況下將不會正確地工作。
正如第 13.2.3 節(jié)中提到的,可序列化事務(wù)僅僅是可重復讀事務(wù)增加了對讀/寫沖突的危險模式的非阻塞監(jiān)控。當檢測到一個可能導致表面的執(zhí)行順序中產(chǎn)生環(huán)的模式,涉及到的一個事務(wù)將被回滾來打破該環(huán)。
如果可序列化事務(wù)隔離級別被用于所有需要一個一致數(shù)據(jù)視圖的寫入和讀取,不需要其他的工作來保證一致性。在PostgreSQL中,來自于其他環(huán)境的被編寫成使用可序列化事務(wù)來保證一致性的軟件應(yīng)該“只工作”在這一點上。
當使用這種技術(shù)時,如果應(yīng)用軟件通過一個框架來自動重試由于序列化錯誤而回滾的事務(wù),它將避免為應(yīng)用程序員帶來不必要的負擔。把default_transaction_isolation
設(shè)置為serializable
可能是個好主意。通過觸發(fā)器中的事務(wù)隔離級別檢查來采取某些動作來保證沒有其他事務(wù)隔離級別被使用(由于疏忽或者為了破壞完整性檢查)也是明智的。
性能建議見第 13.2.3 節(jié)。
這個級別的使用可序列化事務(wù)的完整性保護還沒有擴展到熱備份模式(第 26.5 節(jié))。由于這個原因,那些使用熱備份的系統(tǒng)可能想要在主控機上使用可重復讀和顯式鎖定。
當可以使用非可序列化寫時,要保證一行的當前有效性并保護它不受并發(fā)更新的影響,我們必須使用SELECT FOR UPDATE
、SELECT FOR SHARE
或一個合適的LOCK TABLE
語句(SELECT FOR UPDATE
和SELECT FOR SHARE
鎖只針對并發(fā)更新返回行,而
LOCK TABLE
會鎖住整個表)。當從其他環(huán)境移植應(yīng)用到PostgreSQL時需要考慮這些。
關(guān)于這些來自其他環(huán)境的轉(zhuǎn)換還需要注意的是SELECT FOR UPDATE
不保證一個并發(fā)事務(wù)將不會更新或刪除一個被選中的行。要在PostgreSQL中這樣做,你必須真正地更新該行,即便沒有值需要被改變。SELECT FOR UPDATE
臨時阻塞其他事務(wù),讓它們不能獲取該相同的鎖或者執(zhí)行一個會影響被鎖定行的
UPDATE
或DELETE
,但是一旦正持有該所鎖的事務(wù)提交或回滾,一個被阻塞的事務(wù)將繼續(xù)執(zhí)行沖突操作,除非當鎖被持有時一個該行的實際UPDATE
被執(zhí)行。
在非可序列化MVCC環(huán)境下,全局有效性檢查需要一些額外的考慮。例如,一個銀行應(yīng)用可能會希望檢查一個表中的所有扣款總和等于另外一個表中的收款總和,同時兩個表還會被更新。比較兩個連續(xù)的在讀已提交模式下不會可靠工作的SELECT sum(...)
命令, 因為第二個查詢很可能會包含沒有被第一個查詢考慮的事務(wù)提交的結(jié)果。在一個單一的可重復讀事務(wù)里進行兩個求和則給出在可串行化事務(wù)開始之前提交的所有事務(wù)產(chǎn)生的準確結(jié)果
— 但有人可能會合理地置疑在結(jié)果被遞交的時候,它們是否仍然相關(guān)。 如果可重復讀事務(wù)本身在嘗試做一致性檢查之前應(yīng)用了某些變更,那么檢查的有用性就更加值得討論了, 因為現(xiàn)在它包含了一些(但不是全部)事務(wù)開始后的變化。 在這種情況下,一個小心的人可能希望鎖住所有需要檢查的表,這樣才能獲得一個無可置疑的當前現(xiàn)狀的圖像。 一個SHARE
模式(或者更高)的鎖保證在被鎖定表中除了當前事務(wù)所作的更改之外,沒有未提交的更改。
還要注意如果某人正在依賴顯式鎖定來避免并發(fā)更改,那么他應(yīng)該使用讀已提交模式, 或者是在可重復讀模式里在執(zhí)行命令之前小心地獲取鎖。 在可重復讀事務(wù)里獲取的鎖保證了不會有其它修改該表的事務(wù)正在運行,但是如果事務(wù)看到的快照在獲取鎖之前, 那么它可能早于表中一些現(xiàn)在已經(jīng)提交的更改。 一個可重復讀事務(wù)的快照實際上是在它的第一個查詢或者數(shù)據(jù)修改命令(SELECT
、INSERT
、UPDATE
或
DELETE
)開始的時候凍結(jié)的,因此我們可以在快照凍結(jié)之前顯式地獲取鎖。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: