Postgresql 事务总结
五种并发问题
-
丢失更新: 一个事务覆盖另一个事务已提交的更新数据.
-
dirty read: 一个事务读取到另一个事务还没提交的数据.
-
repeatable read: 一个事务先后读到另一个事务提交之前和之后的数据.
-
phantom read: 事务在操作过程中进行两次查询, 两次结果不一样.
-
serialization anomaly: 成功提交一组事务的结果与每次运行这些事务的顺序不一样.
postgres的隔离级别
ioslate
如何理解事务呢?
举个例子, 从A转100元给B, 需要2条sql,
update account set balance = balance - 100 where name = 'A'
update account set balance = balance + 100 where name = 'B'
- 原子性
我们需要保证要么2个同时发生, 要么都不发生, 这就是由DB的事务来保证的. - 持久性
要在存入硬盘之后再告知成功. - 还有互斥性.
我在给A存钱的时候, 其它人不可以查A的余额, 不然会导致不一致.
如何加事务呢?
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;
更细粒度可以用 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
-
假设我们有个DB, 有个account表, 这个表只有名字和余额.
最开始我们只有一个叫bob的帐户.
init -
现在我们在一个会话里开始一个事务.
BEGIN;
INSERT INTO account(name,balance) VALUES('Alice',10000);
成功之后, 现在我们在当前会话里可以查到alice, 但在其它会话里查不到.
current sessionother session
直到我们commit, 其它会话才可以看到.
网友评论