讓我們在SQL窗口1假設我做的:鎖和交易中的Postgres應該阻止查詢
-- query 1
BEGIN TRANSACTION;
UPDATE post SET title = 'edited' WHERE id = 1;
-- note that there is no explicit commit
從另一個窗口
然後(窗口2)我做的:
-- query 2
SELECT * FROM post WHERE id = 1;
我得到:
1 | original title
由於默認隔離級別是READ COMMITTED,並且因爲查詢1從不提交,因此更改它pe rforms無法讀取,直到我明確地從窗口1.
其實犯,如果我在窗口1,做:
COMMIT TRANSACTION;
然後我可以看到的變化,如果我重新運行查詢2.
1 | edited
我的問題是:
爲什麼查詢返回2罰款,我第一次運行呢?由於窗口1中的事務尚未提交,因此我預計它將被阻止,並且與id = 1
一起放在行上的鎖是(應該是)未發佈的專用應用程序,應該阻止像在窗口2中執行的讀取操作。其餘所有其他對我意義重大,但我期待SELECT
卡住,直到窗口1中的顯式提交被執行。
PostgreSQL使用MVCC(多版本併發控制)而不是鎖。你會獲得較舊的值而不是阻塞。正如你所看到的,這大大提高了併發性,但可能有點難以繞開你的頭。 –
@DanielLyons:說「而不是鎖」將會走向遠...鎖定好了,寫作通常不會阻止閱讀,反之亦然。 –
@ErwinBrandstetter我認爲你讓你的知識深度(這是巨大的)不必要地基於一種常見的誤解來着色一個直接的問題。由於MVCC的原因,OP的預期鎖定方式並非如此。確實有些操作會鎖定,而且無疑某些內部使用鎖定,問題中的任何內容都不會導致預期的鎖定行爲。 –