Postgresql 事務(wù)總結(jié)

Postgresql 事務(wù)總結(jié)

五種并發(fā)問題

  • 丟失更新: 一個事務(wù)覆蓋另一個事務(wù)已提交的更新數(shù)據(jù).

  • dirty read: 一個事務(wù)讀取到另一個事務(wù)還沒提交的數(shù)據(jù).

  • repeatable read: 一個事務(wù)先后讀到另一個事務(wù)提交之前和之后的數(shù)據(jù).

  • phantom read: 事務(wù)在操作過程中進(jìn)行兩次查詢, 兩次結(jié)果不一樣.

  • serialization anomaly: 成功提交一組事務(wù)的結(jié)果與每次運行這些事務(wù)的順序不一樣.

    postgres的隔離級別


    ioslate

如何理解事務(wù)呢?

舉個例子, 從A轉(zhuǎn)100元給B, 需要2條sql,

update account set balance = balance - 100 where name = 'A'
update account set balance = balance + 100 where name = 'B'
  • 原子性
    我們需要保證要么2個同時發(fā)生, 要么都不發(fā)生, 這就是由DB的事務(wù)來保證的.
  • 持久性
    要在存入硬盤之后再告知成功.
  • 還有互斥性.
    我在給A存錢的時候, 其它人不可以查A的余額, 不然會導(dǎo)致不一致.

如何加事務(wù)呢?

default, every single sql is a transaction, we also can use "begin" and "commit" to specific a transaction

BEGIN;
update account set balance = balance - 100 where name = 'A'
update account set balance = balance + 100 where name = 'B'
commit;

更細(xì)粒度可以用 savepoint 和rollback to 來控制.

BEGIN;
update account set balance = balance - 100 where name = 'A'
savepoint update_A_success;
update account set balance = balance + 100 where name = 'B'
rollback to update_A_success;
commit;

Demo

  • 假設(shè)我們有個DB, 有個account表, 這個表只有名字和余額.
    最開始我們只有一個叫bob的帳戶.


    init
  • 現(xiàn)在我們在一個會話里開始一個事務(wù).

    BEGIN;
    INSERT INTO account(name,balance) VALUES('Alice',10000);

成功之后, 現(xiàn)在我們在當(dāng)前會話里可以查到alice, 但在其它會話里查不到.

current session

other session

直到我們commit, 其它會話才可以看到.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容