POSTGRESQL RC事務(wù)處理與ORACLE MySQL 的區(qū)別以及對(duì)PGFANS群里面的問題的實(shí)例分析,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
創(chuàng)新互聯(lián)長(zhǎng)期為上千多家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為特克斯企業(yè)提供專業(yè)的成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè),特克斯網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。
有一個(gè)同學(xué)在PGFANS 群里面提了一個(gè)問題,在他實(shí)驗(yàn)的某個(gè)操作中發(fā)現(xiàn)PG 和 ORACLE 使用同樣的操作流程后,得到的結(jié)果不一致。所以下面準(zhǔn)備驗(yàn)證并找到一些可以解釋的原因。
測(cè)試庫名test
測(cè)試表 test
測(cè)試數(shù)據(jù)
id age
1 20
2 22
3 24
首先我們要確認(rèn) PG 的隔離 RC的模式 ,另外我要排除一些不存在的問題
下面是整個(gè)的操作流程,由于截圖需要截圖好幾個(gè),不利于查看,所以將其變成文字,并序列化, 每行中有執(zhí)行的順序號(hào) 和 屬于的SESSION
1 test=# begin; SESSION 1 #開始SESSION 1
BEGIN
2 test=# select xmin,xmax,cmin,cmax,* from test; SESSION 1
xmin | xmax | cmin | cmax | id | age
---------+------+------+------+----+-----
2027732 | 0 | 0 | 0 | 2 | 40
2027735 | 0 | 1 | 1 | 1 | 20
(2 rows)
#查看當(dāng)前的每行的事務(wù)情況
3 test=# select txid_current_if_assigned(); SESSION 1
txid_current_if_assigned
--------------------------
(1 row)
# 當(dāng)前并未生成事務(wù)號(hào)
4 test=# begin; SESSION 2 # 同時(shí)啟動(dòng)SESSION 2
BEGIN
test=# select * from test; SESSION 2
id | age
----+-----
2 | 40
1 | 20
(2 rows)
# SESSION 2 中查看到的數(shù)據(jù)
5 test=# select txid_current_if_assigned(); SESSION 2
txid_current_if_assigned
--------------------------
(1 row)
6 test=# select txid_current_if_assigned(); SESSION 2
txid_current_if_assigned
--------------------------
(1 row)
7 test=# delete from test where id =1 ; SESSION 1
DELETE 1
test=# select txid_current_if_assigned();
txid_current_if_assigned
--------------------------
2027737
(1 row)
#SESSION 1 刪除了數(shù)據(jù)
8 test=# update test set age = 100 where id =1 ; SESSION 2 WAITING...................
UPDATE 0
test=# select txid_current_if_assigned();
txid_current_if_assigned
--------------------------
2027738
(1 row)
#SESSION 2 更新數(shù)據(jù) 處于等待狀態(tài)
9 test=# select xmin,xmax,cmin,cmax,* from test; SESSION 1
xmin | xmax | cmin | cmax | id | age
---------+------+------+------+----+-----
2027732 | 0 | 0 | 0 | 2 | 40
(1 row)
10test=# select txid_current_if_assigned(); SESSION 1
txid_current_if_assigned
--------------------------
2027737
(1 row)
11 test=# select xmin,xmax,cmin,cmax,* from test; SESSION 2
xmin | xmax | cmin | cmax | id | age
---------+------+------+------+----+-----
2027732 | 0 | 0 | 0 | 2 | 40
2027737 | 0 | 1 | 1 | 1 | 20
(2 rows)
#SESSION 1 插入數(shù)據(jù)
12 test=# insert into test (id,age) values (1,20); SESSION 1
INSERT 0 1
test=# select txid_current_if_assigned();
txid_current_if_assigned
--------------------------
2027737
(1 row)
13 test=# select xmin,xmax,cmin,cmax,* from test; SESSION 1
xmin | xmax | cmin | cmax | id | age
---------+------+------+------+----+-----
2027732 | 0 | 0 | 0 | 2 | 40
2027737 | 0 | 1 | 1 | 1 | 20
(2 rows)
14 test=# commit; SESSION 1
COMMIT
#SESSION 1 COMMIT
15 test=# select xmin,xmax,cmin,cmax,* from test; SESSION 1
xmin | xmax | cmin | cmax | id | age
---------+------+------+------+----+-----
2027732 | 0 | 0 | 0 | 2 | 40
2027737 | 0 | 1 | 1 | 1 | 20
(2 rows)
16 test=# commit; SESSION 2
COMMIT
#SESSION 2 COMMIT
17 test=# select xmin,xmax,cmin,cmax,* from test; SESSION 2
xmin | xmax | cmin | cmax | id | age
---------+------+------+------+----+-----
2027732 | 0 | 0 | 0 | 2 | 40
2027737 | 0 | 1 | 1 | 1 | 20
(2 rows)
結(jié)果:SESSION 2 不會(huì)更新 SESSION 1中后插入的數(shù)據(jù)。
從上面的步驟中我們能看到或者領(lǐng)會(huì)到PG 的那些特性
事務(wù)ID 是自增的
每行數(shù)據(jù)會(huì)用(t_xmin, t_xmax)來標(biāo)示自己的可用性
t_xmin 存儲(chǔ)的是產(chǎn)生這個(gè)元組的事務(wù)ID,可能是insert或者update語句t_xmax 存儲(chǔ)的是刪除或者鎖定這個(gè)元組的XID
事務(wù)只能看見t_xmin比自己XID 小且沒有被刪除的元組
以上是官方文檔中的提示,已經(jīng)明確的說明了上述的問題,并且也給出了一些建議。
那我們的工作到底完成了沒有,沒有,我們提升PG 的隔離級(jí)別到 RR.
結(jié)果如下:
SESSION 1
SESSION 2
在將SESSION的級(jí)別提升后,結(jié)果就變化了,再次在SESSION 2中操作,直接報(bào)錯(cuò)。
最后的問題是,提出問題的同學(xué)反映ORACLE 與PG的在類似的環(huán)節(jié)情況下,反饋的情況不一。同時(shí)我這邊也通過MYSQL 8 來將上述的操作同樣做了,與那位同學(xué)反映的情況一樣。
個(gè)人認(rèn)為這并不是PG數(shù)據(jù)庫本身的缺陷,這是一種數(shù)據(jù)庫處理某種復(fù)雜情況和隔離級(jí)別對(duì)數(shù)據(jù)一致性的一種取舍。
如果遇到這樣的情況如何操作,有如下建議
1 可以提高數(shù)據(jù)庫的隔離級(jí)別到RR (如果你的數(shù)據(jù)庫中有類似業(yè)務(wù)或操作)
2 在設(shè)計(jì)業(yè)務(wù)邏輯時(shí),通過邏輯刪除而不是物理刪除來對(duì)業(yè)務(wù)表進(jìn)行操作。
3 可以在操作時(shí)添加 selecr for update 類似這樣的語句對(duì)于數(shù)據(jù)的可操作性進(jìn)行一個(gè)確認(rèn)。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。