1、将数据改变分组到逻辑单元
PostgreSQL 中,这些改变由四个关键语法来控制:
BEGIN 开始一个事务SAVEPOINT savepointname告诉服务器需要记住事务的当前状态。这个语法只能在 BEGIN之后且在 COMMIT
或者 ROLLBACK 之前;也就是说,必须在一个事务中。COMMIT 表明所有的事务的元素都完成了,现在需要对所有的并行的事务和子事务进行持久化并对使其结果
(在本事务之外)可访问。ROLLBACK [TO savepointname] 表明这个事务将被放弃,SQL 事务中所有对数据的改变将被取消。数据库给
所有用户的表现是从 BEGIN 开始的任何改变都没有发生,且事务被关闭。另一个带 TO 从句的版本允许我们回滚到一个命名的保存点,且不完成这个事务
2、事务和保存点:
如果我们需要回滚一个事务中的一些操作,我们可以建立一个我们待会儿可以回滚回去的命名的保存点,而不是回滚到我们从 BEGIN 语句开始的地方。
test=> BEGIN;
BEGIN
test=> INSERT INTO ttest2 (ival2, sval2) VALUES (42, 'Arthur');
INSERT 17796 1
test=> SAVEPOINT first;
SAVEPOINT
test=> UPDATE ttest1 SET sval1 = 'Robert' WHERE ival1 = 1;
UPDATE 1
test=> SELECT * FROM ttest1;
ival1 | sval1
-------+--------1 | Robert
(1 row)
test=> ROLLBACK TO first;
ROLLBACK
test=> SELECT * FROM ttest1;
ival1 | sval1
-------+-------1 | David
(1 row)
test=> SELECT * FROM ttest2;
ival2 | sval2
-------+--------42 | Arthur
(1 row)
test=>
test=> ROLLBACK;
ROLLBACK
test=> SELECT * FROM ttest1;
ival1 | sval1
-------+-------1 | David
(1 row)
test=> SELECT * FROM ttest2;
ival2 | sval2
-------+-------
(0 rows)
test=>
在 PostgreSQL(或大多数其他的关系型数据库中)你不能嵌套事务。在 PostgreSQL 中,如果你尝试在一个事务中执行一个 BEGIN 语句,PostgreSQL 将产生一个警告消息,告诉你已经有一个事务在进行中。
3、ANSI 隔离级别
ANSI 隔离级别和不良现象的对照:
隔离级别 脏读 不可重复读 幻读
Read Uncommitted(读未提交) 允许 允许 允许
Read Committed(读已提交) 不允许 允许 允许
Repeatable Read(重复读) 不允许 不允许 允许
Serializable(串行化) 不允许 不允许 不允许
可以通过使用 SET TRANSACTION ISOLATION LEVEL 命令改变隔离级别,以下为语法:
SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE }
除非有很好的理由改变它,否则我们建议你不要改变你的 PostgreSQL 数据库中的默认的隔离级别。
4、锁
大多数数据库实现了事务,特别是当隔离不同用户之间的事务的时候,使用锁来在用户间约束对数据的访问。简单来讲,有两种锁:
共享锁,允许其他用户读,但不允许修改数据
排他锁,甚至避免其他事务读数据
锁定表:
在 PostgreSQL 中,也可以锁住表,虽然我们强烈建议你避免这样做,坚持使用 SQL 标准的机制来确保客户的隔离。锁定表的语法如下:
LOCK [ TABLE ] table-name
LOCK [ TABLE ] table-name IN [ ROW | ACCESS ] { SHARE | EXCLUSIVE } MODE
LOCK [ TABLE ] table-name IN SHARE ROW EXCLUSIVE MODE