【PostgreSQL】事务、并发、锁

ACID

原子性(atomicity)

事务必须以一个整体单元的形式进行工作,对于其数据的修改,要么全都执行,要么全都不执行。如果只执行事务中多个操作的前半部分就会出现错误,那么必须回滚所有的操作,让数据在逻辑上回滚到先前的状态。

一致性(consistency)

事务在完成时,必须使所有的数据都保持一致状态。

隔离性(isolation)

事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务是不会查看中间状态的数据。

持久性(durability)

事务完成之后,它对于系统的影响是永久性的。即使今后出现致命的系统故障(如机器重启、掉电),数据也将一直保持。

事务的使用

在psql的默认配置下,自动提交“AUTOCOMMIT"项是打开的,也就是说,每执行一条SQL语句,都会自动提交。可以设置psql中的内置变量“AUTOCOMMIT”来关闭自动提交:

\set AUTOCOMMIT off

另一种方法:使用 BEGIN; 其相当于关闭了自动提交

begin;
<sql语句>
rollback;

SAVEPOINT

建立保存点,可以建立多个,若后面的语句执行失败,则回滚到这个保存点。

  1. 使用 begin; 启动一个事务;
  2. <sql语句>
  3. savepoint savepoint01; 建一个保存点"savepoint01"
  4. <sql语句>
  5. 若4.中的语句失败,可以回滚到上一个保存点。 rollback to savepoint01;
  6. 回滚之后再执行sql语句
  7. commit;

事务隔离级别

  • READ UNCOMMITTED:读未提交
  • READ COMMITTED:读已提交
  • REPEATABLE READ:重复读
  • SERIALIZABLE:串行化

脏读:
一个事务读取了另一个未提交事务写人的数据。这是最不希望发生的,因为如果发生了脏读,则在并发控制上,应用程序会变得很复杂。
不可重复读:
指一个事务重新读取前面读取过的数据时,发现该数据已经被另一个已提交事务修改了。在大多数情况下,这还是可以接受的,只是在少数情况下会出现问题。
幻读:
一个事务开始后,需要根据数据库中现有的数据做一些更新,于是重新执行一个查询,返回一套符合查询条件的行,这时发现这些行因为其他最近提交的事务发
生了改变,导致现有的事务如果再进行下去就可能会在逻辑上出现一些错误。
事务隔离级别的行为见下图:

死锁及防范

死锁的发生必须具备以下四个必要条件。

  • 互斥条件:指事务对所分配到的资源加了排他锁,即在一段时间内只能由一个事务加锁占用。如果此时还有其他进程请求排他锁,则请求者只能等待,直至持有排他锁的事务释放为止。
  • 请求和保持条件:指事务已经至少持有了一把排他锁,但又提出了新的排他锁请求,而该资源上的排他锁已被其他事务占有,此时请求被阻塞,但同时它对自己已获得的排他锁又保持不放。
  • 不剥夺条件:指事务已获得的锁,在未使用完之前,不能被其他进程剥夺,只能在使用完时由自己释放。
  • 环路等待条件:指在发生死锁时,必然存在一个事务-资源的环形链,即事务集合{T0, T1, T2,.,. Tn}中的T0正在等待一个T1持有的排他锁; P1 正在等待P2持
    有的排他锁,… Pn正在等待PO持有的排他锁。

防止死锁的最好方法通常是保证所有使用一个数据库的应用都以相同的顺序在多个对象上请求排他锁。比如,在应用编程中,人为规定在一个事务中只能以一个固定顺序来更新表。假设在数据库中,有A. B、C、D四张表,现规定只能按如下顺序修改这几张表:“B→C→A→D",若某个进程先更新了A表,然后又想更新C表,则必须先回滚先前对A表的更新,然后再按规定的顺序,先更新C表,再更新A表。

由于数据库可以自动检测出死锁,所以应用也可以通过捕获死锁异常来处理死锁。但这不是一个很好的方法,因为数据库检测死锁需要一定的代价,可能会导致应用程序过久地持有排他锁,从而致使系统的并发处理能力下降。排他锁持有的时间越长,就越容易导致死锁,所以在程序设计时要尽量短地持有排他锁。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jsonCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值