Postgresql中提供多种机制保证数据完整性。例如约束、触发器、事务和锁管理等。
Postgresql一个特点是并发控制机制,在维护一致性和完整性时,尽量避免堵塞读写。
在Postgresql中,使用多版本并发控制(MVCC)维护数据一致性,相对于锁定模型,多版本控制系统主要优点是读(检索)数据和写数据锁请求不互相冲突,读写不互相阻塞。传统数据库,为维护数据一致性和完整性,避免一个事务读写到其它并发事务更新所产生不一致数据,通常采用就会使用LOCK机制。付出成本就是,当锁请求无法被响应时,待处理请求必须进入等候队列,甚至等待超时不被处理。
在日常数据库操作中,一般情况下我们对于一组操作通常希望能够全部成功或失败,即不允许部分成功情况发生。一组操作,要么全部执行完毕,要么完全执行失败,类似操作被称为事务。
数据库管理系统(DBMS)中,事务(transaction)具有四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability),合并缩写为ACID。.
原子性是指事务是一个不可再分割工作单元,事务中全部操作要么全部执行,要么都不执行,如果中途出现错误,需要回滚已完成所有操作,让数据恢复到未执行操作前状态。
一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
对于并发事务,我们不希望发生不一致情况,根据产生不一致结果严重情况,分为脏读、不可重复读 、幻读和序列化异常。
脏读是一个事务读取另一个事务未完整提交时数据,该事务执行存在失败可能性,数据有可能回滚到初始状态,导致读取错误数据,因此最不希望发生。
针对同一个数据,前一个事务内多次查询,由于期间后一个事务同时在提交数据,前一个事务重复读取后一个事务数据导致执行结果不同,即前一个事务执行结果不一致,出现不可重复读,少数情况下,可能会出现问题。
幻读是指执行两个完全相同查询,第二次查询所返回结果集与第一次查询不相同,幻读可能导致事务出现逻辑错误。
序列化异常是指成功提交一组事务执行结果与这些事务可串行执行结果不一致。
sql标准定义四个级别事务隔离,分别是读未提交(read uncommitted)、读已提交(read committed)、可重复读(repeatable read)和可串行化(serializable)。可串行化通过数据库标准定义,保证并发和顺序执行结果相同;其他三个级别是通过现象定义的。
不同事物隔离级别行为各不相同,读未提交可能出现脏读;读未提交和读已提交可能导致不可重复读,读未提交、读已提交和重复读可能导致幻读。
Postgresql可以使用命令设置任意一种事务隔离级别,实际上只有读已提交和可串行化两种。读已提交是Postgresql中的默认隔离级别。
Postgresql支持两段提交协议。两段提交是2台以上数据库实现原子性关键技术。
Postgresql存在表级锁和行级锁。当执行查询、插入、更新、删除等操作时,首先需要获取表级锁,再获取行级锁。
死锁是指两个不同事务相互影响,导致两个事务均无法正常执行。例如2个事务操作2个不同表时存在两个排斥锁互相请求对方表排斥锁,两个事务均无法正常执行。
当事务设计不严谨时,可能会导致锁等待很严重,甚至出现死锁,严重影响数据库正常运行。
参考链接
http://www.jianshu.com/p/04b542aeebac
https://www.postgresql.org/docs/10/static/transaction-iso.html
参考书籍
Postgresql 修炼之道 从小工到专家 P203-P220