当前位置: 代码迷 >> 综合 >> PostgreSQL 事务和锁
  详细解决方案

PostgreSQL 事务和锁

热度:143   发布时间:2023-09-19 14:49:47.0

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

 

  相关解决方案