pgsql中的事务隔离级别

前言

最近在学习pgsql里面的锁,但是忽然发现对于事物的隔离有点模糊,不能很好的进行知识的串联。那么就来认真总结下吧。

事物隔离级别

这是官方文档的描述

SQL标准定义了四种隔离级别。最严格的是可序列化,在标准中用了一整段来定义它,其中说到一组可序列化事务的任意并发执行被保证效果和以某种顺序一个一个执行这些事务一样。其他三种级别使用并发事务之间交互产生的现象来定义,每一个级别中都要求必须不出现一种现象。注意由于可序列化的定义,在该级别上这些现象都不可能发生(这并不令人惊讶--如果事务的效果与每个时刻只运行一个的相同,你怎么可能看见由于交互产生的现象?)。

四种事务隔离级别分别是:

读未提交

读已提交

可重复读

可序列化

在各个级别上被禁止出现的现象是

脏读

一个事物读取了另一个并行未提交事物写入的数据。

不可重复读

一个事物重新读取之前的数据,发现这个数据已经被另一个事物(在初读之后提交)修改。

幻读

一个事物重新执行了一个返回符合条件的行集合的查询,发现满足条件的行集合因为另一个最近提交的事物发生了改变。

序列化异常

成功提交一组事物的结果与这些事物所有可能串行执行结果不一致。

在PostgreSQL中,你可以请求四种标准事务隔离级别中的任意一种,但是内部只实现了三种不同的隔离级别,即 PostgreSQL 的读未提交模式的行为和读已提交相同。这是因为把标准隔离级别映射到 PostgreSQL 的多版本并发控制架构的唯一合理的方法。

读已提交隔离级别

读已提交是pgsql中默认的隔离级别。当一个事务使用这个隔离级别时,一个查询(没有FOR UPDATE/SHARE子句)只能看到查询开始之前已经

被提交的数据,而无法看到未提交的数据或在查询执行期间其他事物提交的数据。

在不同的事务之间:SELECT查询看到的是一个在查询开始运行的瞬间该数据库的一个快照,当一个事务a对数据进行了修改,a事务还没有提交的时候另一个事务b查询到的数据就是,事务a未修改之前的数据,也就是查询开始之前的瞬间,数据库的一个快照。

在同一个事务之间:SELECT可以看见在它自身事务中之前执行的更新的效果,即使它们还没有被提交。也就是更新完成之后的数据,是马上可以被查询到的,这就造成了,在同一个事务之间先后查询的结果可能不一样,当更新操作在两个查询之间进行,后面的查询就是更新后的数据了。

UPDATE、DELETE、SELECT FOR UPDATE和SELECT FOR SHARE命令在搜索目标行时的行为和SELECT一样: 它们将只找到在命令开始时已经被提交的行。 不过,在被找到时,这样的目标行可能已经被其它并发事务更新(或删除或锁住)。在这种情况下, 即将进行的更新将等待第一个更新事务提交或者回滚(如果它还在进行中)。 如果第一个更新事务回滚,那么它的作用将被忽略并且第二个事务可以继续更新最初发现的行。 如果第一个更新事务提交,若该行被第一个更新者删除,则第二个更新事务将忽略该行,否则第二个更新者将试图在该行的已被更新的版本上应用它的操作。该命令的搜索条件(WHERE子句)将被重新计算来看该行被更新的版本是否仍然符合搜索条件。如果符合,则第二个更新者使用该行的已更新版本继续其操作。在SELECT FOR UPDATE和SELECT FOR SHARE的情况下,这意味着把该行的已更新版本锁住并返回给客户端。

可重复读隔离级别

可重复读隔离级别只能看到事物之前提交的数据;它从来看不到未提交的数据或者并行

事物在本事务执行期间提交的修改。(不过,查询能够看见在它的事务中之前执行的更新,即使它们还没有被提交)。

这个级别与读已提交不同之处在于,一个可重复读事务中的查询可以看见在事务中第一个非事务控制语句开始时的一个快照,而不是事务中当前语句开始时的快照。因此,在一个单一事务中的后续SELECT命令看到的是相同的数据,即它们看不到其他事务在本事务启动后提交的修改。

UPDATE、DELETE、SELECT FOR UPDATE和SELECT FOR SHARE命令在搜索目标行时的行为和SELECT一样: 它们将只找到在事务开始时已经被提交的行。 不过,在被找到时,这样的目标行可能已经被其它并发事务更新(或删除或锁住)。在这种情况下, 可重复读事务将等待第一个更新事务提交或者回滚(如果它还在进行中)。 如果第一个更新事务回滚,那么它的作用将被忽略并且可重复读事务可以继续更新最初发现的行。 但是如果第一个更新事务提交(并且实际更新或删除该行,而不是只锁住它),则可重复读事务将回滚并带有如下消息

ERROR:  could not serialize access due to concurrent update

因为一个可重复读事务无法修改或者锁住被其他在可重复读事务开始之后的事务改变的行。

可序列化隔离级别

可序列化隔离级别提供了最严格的事务隔离。这个级别为所有已提交事务模拟序列事务执行;就好像事务被按照序列一个接着另一个被执行,而不是并行地被执行。但是,和可重复读级别相似,使用这个级别的应用必须准备好因为序列化失败而重试事务。事实上,这个隔离级别完全像可重复读一样地工作,除了它会监视一些条件,这些条件可能导致一个可序列化事务的并发集合的执行产生的行为与这些事务所有可能的序列化(一次一个)执行不一致。这种监控不会引入超出可重复读之外的阻塞,但是监控会产生一些负荷,并且对那些可能导致序列化异常的条件的检测将触发一次序列化失败。

摘录

【PostgreSQL 11.2 手册】http://postgres.cn/docs/11

pgsql中的事务隔离的更多相关文章

  1. Net Core中数据库事务隔离详解——以Dapper和Mysql为例

    Net Core中数据库事务隔离详解--以Dapper和Mysql为例 事务隔离级别 准备工作 Read uncommitted 读未提交 Read committed 读取提交内容 Repeatab ...

  2. Hibernate中的事务隔离问题(脏读、不可重复读、幻读)

    Hibernate中的事务隔离问题(脏读.不可重复读.幻读) 1.事务的特性 事务的四个特性: 1)原子性:事务是进行数据库操作的最小单位,所以组成事务的各种操作是不可分割的 2)一致性:组成事务的各 ...

  3. Sql Server中的事务隔离级别

    数据库中的事物有ACID(原子性,一致性,隔离性,持久性)四个特性.其中隔离性是用来处理并发执行的事务之间的数据访问控制.SqlServer中提供了几种不同级别的隔离类型. 概念 Read UnCom ...

  4. 重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系

    重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系 Innodb中的事务隔离级别和锁的关系 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁 ...

  5. 在MySQL中设置事务隔离级别有2种方法:

    在MySQL中设置事务隔离级别有2种方法: 1 在my.cnf中设置,在mysqld选项中如下设置 [mysqld] transaction-isolation = READ-COMMITTED 2 ...

  6. Innodb中的事务隔离级别和锁的关系(转载)

    nodb中的事务隔离级别和锁的关系 原文:https://tech.meituan.com/innodb-lock.html ameng ·2014-08-20 15:50 前言: 我们都知道事务的几 ...

  7. 【转载】Innodb中的事务隔离级别和锁的关系

    前言 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所 ...

  8. Innodb中的事务隔离级别和锁的关系

    前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力. ...

  9. Java中线程的锁和数据库中的事务隔离级别

    当涉及到两个或多个线程操作同一个资源时,就会出现锁的问题. 数据库中的某一条记录或者是某一个对象中的字段,可以修改,也可以读取,一般情况下,读取的那个方法应该加锁(即用synchronized互斥), ...

随机推荐

  1. 死磕Lambda表达式(四):常用的函数式接口

    失去人性,失去很多:失去兽性,失去一切.--<三体> 在Java8支持Lambda表达式以后,为了满足Lambda表达式的一些典型使用场景,JDK为我们提供了大量常用的函数式接口.它们主要 ...

  2. Scapy编写UDP扫描脚本

    脚本内容如下: from scapy.all import * import optparse import threading def scan(target,port): pkt=IP(dst=t ...

  3. NDCG的理解

    2019-05-29 14:15:44

  4. 报错:Error updating database. Cause: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'gender' at row 1

    我遇到这个错误是解决办法:我修改了对应的数据库字段的长度:原本我设置的是char型,但是存进去的是一个string型,结果就报了这个报了这个错误 下面就是数据库修改之后的结果. 以上都是我学习过程中遇 ...

  5. Git提交代码的流程——新手适用

    pull:是下拉代码,相等于将远程的代码下载到你本地,与你本地的代码合并push:是推代码,将你的代码上传到远程的动作完整的流程是: 第一种方法:(简单易懂) 1.git add .(后面有一个点,意 ...

  6. 主从校验工具pt-table-checksum和pt-table-sync工作原理

    pt-table-checksum和pt-table-sync是常用来做MySQL主从数据一致性校验的工具,pt-table-checksum只校验数据,不能对数据进行同步:pt-table-sync ...

  7. 5L-链表导论心法

    链表是比数组稍微复杂一点的数据结构,也是两个非常重要与基本的数据结构.如果说数组是纪律严明排列整齐的「正规军」那么链表就是灵活多变的「地下党」. 关注公众号 MageByte,有你想要的精彩内容. 链 ...

  8. [算法笔记] PAT-ADV-1020

    题目要求:给出二叉树的后序遍历序列和中序遍历序列,输出二叉树的层次遍历序列. (传送门) Sample Input 7 2 3 1 5 7 6 4 1 2 3 4 5 6 7 Sample Outpu ...

  9. 结合生活,剖析《生产者消费者模型》-java多线程(一)

    博客园的园友们好,看博客园上各位大佬的文章,已陪伴了我程序员职业的三年, 如今自己同样希望能把自己从小白到菜鸟的成长过程分享给大家.不定期更新!!! 首先我本人智商不高,理解问题十分吃力,完全不属于天 ...

  10. 【深度强化学习】Curriculum-guided Hindsight Experience Replay读后感

    目录 导读 目录 正文 Abstract[摘要] Introduction[介绍] 导读 看任何一个领域的文章,一定要看第一手资料.学习他们的思考方式,论述逻辑,得出一点自己的感悟.因此,通过阅读pa ...