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. idea 新建java类自动补充创建人,创建时间,版本等..

    1.先进入 File 2.进入 Editor 找到 File and Code Templates 并点击 3.右侧点击 lncludes  4.第二项 File Header  /** * @aut ...

  2. 8千字干货教程|java反射精讲

    java反射机制精讲 目录 1. 反射机制的概念 2. 反射的基础Class类 3. 反射的用法 4. 反射的应用示例 作者简介:全栈学习笔记,一个正在努力的人 微信公众号:公众号日更,精彩美文每天推 ...

  3. 什么是CPU load

    最近经常收到告警,CPU load大于阈值告警.查看系统的CPU是12核,告警阈值设置的是8.对于CPU load一直有个模糊的概念,具体是什么意思还真搞不明白,趁这个机会好好搞搞究竟. 1.查看CP ...

  4. webpack配置打包vue文件

    1.首先全局安装node,和npm.检查是否安装成功 2.新建一个文件下,进入该文件夹. 前先执行 npm init -y 然后就会在文件夹下出现一个package.json文件 然后执行 npm i ...

  5. 区间dp暂时的理解

    因为刚刚看了区间dp,所以写一下对区间dp的理解. 例题: 石子归并 51Nod - 1021 看了一篇博客,觉得他说得比较容易理解,所以再次重复一遍: 假如你是上帝,已经知道了1~n堆石子的最优解, ...

  6. Prism+MaterialDesign+EntityFramework Core+Postgresql WPF开发总结 之 基础篇

    本着每天记录一点成长一点的原则,打算将目前完成的一个WPF项目相关的技术分享出来,供团队学习与总结. 总共分三个部分: 基础篇主要争对C#初学者,巩固C#常用知识点: 中级篇主要争对WPF布局与美化, ...

  7. Python python对象 range

    """ range(stop) -> range object range(start, stop[, step]) -> range object Retu ...

  8. 如何查看自己项目中vue的版本号和cli的版本号

    查看Vue版本号 代码方式 npm list vue 其他方式 找到package.json文件夹 找"dependencies"然后就可以看到你装的vue的版本了 查看cli版本 ...

  9. 使用tensorflow的softmax进行mnist识别

    tensorflow真是方便,看来深度学习需要怎么使用框架.如何建模- ''' softmax classifier for mnist created on 2019.9.28 author: vi ...

  10. [vios1023]维多利亚的舞会3<强联通分量tarjan>

    题目链接:https://vijos.org/p/1023 最近在练强联通分量,当然学的是tarjan算法 而这一道题虽然打着难度为3,且是tarjan算法的裸题出没在vijos里面 但其实并不是纯粹 ...