PG数据库事务隔离级别「建议收藏」

PG数据库事务隔离级别「建议收藏」Postgres数据库事务隔离级别介绍

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

Postgres数据库事务隔离级别介绍


0. What is Database Transaction?

数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的一个逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。 —— [百度百科]

  • A –Atomicity
    事务必须是原子工作单元;要么全都执行成功,要么全都执行不成功。通常,与某个事务关联的操作具有共同的目标,并且是相互依赖的。如果系统只执行这些操作的一个子集,则可能会破坏事务的总体目标。原子性消除了系统处理操作子集的可能性。
  • C –Consistency
    一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态
    拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。
  • I –Isolation
    隔离性是当并发访问数据库时,数据库每一个事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离
    即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
  • D –Durability
    事务完成之后,它对于系统的影响是永久性的,该修改即使出现致命的系统故障也将一直保持

1. Why Isolation is important for DataBase?

如果不考虑事务隔离性,可能导致以下几种严重的问题

(1) 脏读

脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。

当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。例如:用户A向用户B转账100元,对应SQL命令如下。

update account set money = money + 100 where name = 'B';  (此时A通知B)
update account set money = money - 100 where name = 'A';

当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。

(2) 不可重复读

不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。

例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。

不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如对于同一个数据A和B依次查询就可能不同,A和B就可能打起来了……

(3) 幻读

幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。

幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

为了解决并发导致的不一致问题(脏读/不可重复读/幻读),SQL标准提出了四种事务隔离级别

隔离级别 脏读 不可重复读 幻读
读未提交 可能 可能 可能
读已提交 不可能 可能 可能
可重复读 不可能 不可能 可能
可序列化 不可能 不可能 不可能

2. How Postgres handle with isolation?

在PostgreSQL中,你可以请求四种标准事务隔离级别中的任意一种。 但是在内部,实际上只有三种不同的隔离级别,分别对应级别读已提交、可重复读和可串行化。但你你选择了读未提交级别,实际上你得到的是读已提交,并且在PostgreSQL的可重复读实现中幻读是不可能出现的,所以实际的隔离级别可能比你选择的更严格。这是 SQL 标准允许的: 四种隔离级别只定义了哪种现像不能发生,但是没有定义哪种现像一定发生。PostgreSQL只提供三种隔离级别的原因是, 这是把标准的隔离级别映射到多版本并发控制架构的唯一合理方法。 可用的隔离级别的行为在下面小节中详细描述。

要设置一个事务的事务隔离级别,使用SET TRANSACTION命令。

重要: 某些PostgreSQL数据类型和函数关于事务的行为有特殊的规则。特别是,对一个序列的修改(以及用serial声明的一列的计数器)是立刻对所有其他事务可见的,并且在作出该修改的事务中断时也不会被回滚。

(1) 读已提交隔离级别

读已提交是PostgreSQL中的默认隔离级别。 当一个事务运行使用这个隔离级别时, 一个查询(没有FOR UPDATE/SHARE子句)只能看到查询开始之前已经被提交的数据, 而无法看到未提交的数据或在查询执行期间其它事务提交的数据。实际上,SELECT查询看到的是一个在查询开始运行的瞬间该数据库的一个快照。不过SELECT可以看见在它自身事务中之前执行的更新的效果,即使它们还没有被提交。还要注意的是,即使在同一个事务里两个相邻的SELECT命令可能看到不同的数据, 因为其它事务可能会在第一个SELECT开始和第二个SELECT开始之间提交。

读已提交模式提供的部分事务隔离对于许多应用而言是足够的,并且这个模式速度快并且使用简单。 不过,它不是对于所有情况都够用。做复杂查询和更新的应用可能需要比读已提交模式提供的更严格一致的数据库视图。

(2) 可重复读隔离级别

可重复读隔离级别只看到在事务开始之前被提交的数据;它从来看不到未提交的数据或者并行事务在本事务执行期间提交的修改(不过,查询能够看见在它的事务中之前执行的更新,即使它们还没有被提交)。这是比SQL标准对此隔离级别所要求的更强的保证,并且阻止脏读/不可重复读/幻读 所有现象。如上面所提到的,这是标准特别允许的,标准只描述了每种隔离级别必须提供的最小保护。

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

可重复读模式提供了一种严格的保证,在其中每一个事务看到数据库的一个完全稳定的视图。不过,这个视图并不需要总是和同一级别上并发事务的某些序列化(一次一个)执行保持一致。例如,即使这个级别上的一个只读事务可能看到一个控制记录被更新,这显示一个批处理已经被完成但是不能看见作为该批处理的逻辑组成部分的一个细节记录,因为它读取空值记录的一个较早的版本。如果不小心地使用显式锁来阻塞冲突事务,尝试用运行在这个隔离级别的事务来强制业务规则不太可能正确地工作。

(3) 可序列化隔离级别

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


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/183298.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 网站推荐:11个相似图片搜索网站(以图找图)

    网站推荐:11个相似图片搜索网站(以图找图)你想凭着一张现有图片找出它的原始图片,或者是凭着一张小的缩略图找出原始大图吗?下面的十款搜索引擎可以帮你实现,以图找图,以图搜图,以图片搜索相似的图片。一:http://tineye.com/Tineye是典型的以图找图搜索引擎,输入本地硬盘上的图片或者输入图片网址,即可自动帮你搜索相似图片,搜索准确度相对来说还比较令人满意。TinEye是加拿大Idée公司研发…

  • request.getParameterNames_request和urllib区别

    request.getParameterNames_request和urllib区别Servlet中request.getParameter和getParameterValues getParameterNames三者区别1.request.getParameter:获取前台表单单个元素name对应的value值2.request.getParameterValues:获取前台表单多个标签同名name对应的所有value值3.request.getParameterN…

  • 散列的基本概念

    散列的基本概念散列的基本概念什么是散列?为什么需要散列?散列是一种思想。与已经学过的其他数据结构相比较,向量是采用循秩访问(callbyrank)的访问方式,列表是采用循位置访问(callbyposition)的访问方式,二叉搜索树是采用循关键码访问(callbykey)的访问方式,散列与他们都不一样,是采用循值访问(callbyvalue)的访问方式。举个例子,你现在身处同济大学嘉定…

  • Alex 的 Hadoop 菜鸟教程: 第21课 不只是在HBase中用SQL:Phoenix

    Alex 的 Hadoop 菜鸟教程: 第21课 不只是在HBase中用SQL:Phoenix什么是Phoenix?Phoenix的团队用了一句话概括Phoenix:”WeputtheSQLbackinNoSQL”意思是:我们把SQL又放回NoSQL去了!这边说的NoSQL专指HBase,意思是可以用SQL语句来查询Hbase,你可能会说:“Hive和Impala也可以啊!”。但是Hive和Impala还可以查询文本文件,Phoenix的特点就是,它只能查Hbase,别的类型都不支持!但是也因为这种专一的态度,让Phoenix在Hbase上查询的性能超过了Hive和Impala!

  • vue $listeners $attr_vue query

    vue $listeners $attr_vue query1、vm.$attrs2.4.0新增类型{[key:string]:string}只读详细包含了父作用域中不作为prop被识别(且获取)的特性绑定(class和style除外)。当一个组件没有声明任何prop时,这里会包含所有父作用域的绑定(class和style除外),并且可以通过v-bind=”$attrs”传入内部组件——在创建高级别的组件时非常有用。简单点讲就是包含了所有父组件在子组件上设置的属性(除了prop传递的属性、class和styl

    2022年10月10日
  • 【分享】深入浅出WPF全系列教程及源码

    【分享】深入浅出WPF全系列教程及源码

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号