关于postgresql中事务隔离的总结

1 介绍

具有基本知识的DBA都知道,PostgreSQL在控制数据的一致性是通过使用一种多版本模型来维护的,也就是常说的多版本并发控制MVCC。这也就意味着每一个sql语句看到的都只是一小段时间的数据库快照,或者称为版本,而并不关心底层的数据文件当中的当前状态。这样带来的好处就是保护每一个会话中的事务不受到其他会话的影响,提供了非常好的事务隔离机制。MVCC并发控制模型相对于锁机制的优点在于,查询数据的锁请求与写数据的锁请求并不冲突,所以,读不会阻塞写,写也不会阻塞读。

2 事务隔离

其实说起事务隔离,可能偏向于理论上一些,但是对于数DBA人员来说,这个需要牢牢掌握,因为很多时候在排查异常问题的时候,需要分析每一个sql、每一个事务都对数据库进行了哪些操作,为什么会导致数据不一致的原因等等。

sql标准定义了四种隔离级别:读未提交、读已提交、读可重复、可序列化。四种关系层层递进,越来越严格。

  • 读未提交 Read uncommitted
    解释就是一个事务读到了另一个事务未提交的数据,一旦另一个事务回滚了,那么读到的数据就是有问题的。这种现象就是脏读了。
  • 读已提交 Read committed
    读已经提交的数据能够解决脏读的问题,因为这个事务需要等待另一个事务提交后才能读取数据。但是该级别有一个问题,重复读的时候可能会产生不同的数据,这是因为该事务读取的两次过程中,这些数据并没有锁住 ,还是可以处于能够修改(update和delete)的。该级别是postgresql默认的级别。
  • 读可重复 Repeatable read
    该级别解决了读已提交的不可重复读的问题,在事务开启的时候,不能再修改操作了,直到该事务提交。该级别是mysql,Oracle,sql server默认的级别。但是在该级别,还是会出现幻读的问题,幻读和可重复读非常类似,都是两次查询的结果不一致,可以这么理解,一个事务在插入一个检查过不存在的记录时,发现数据已经存在了,之前检查的结果就像幻觉一样,这是因为已经插入了新的数据导致的。

区别需要从机制来看,读某一行数据,会给行加行排他锁,事务无法修改数据,重复读就不会出现数据不一致的问题,但是并没有加表锁,还是可以insert数据的。这就导致了后面查询数据变多了。mysql会出现幻读,pg不会。

  • 序列化 Serializable
    序列化是最高的事务隔离级别,在该级别下,事务是按照串行化的顺序执行,可以避免脏读,重复读,幻读。但是可想而知,所有事务都是按照串行化顺序执行,那怎么保证高并发呢?这种数据库必然性能非常低下,几乎没有数据库会达到这种级别。

下表概括了SQL标准和PG实现的事务隔离级别中的描述

隔离级别 脏读 不可重复读 幻读 序列化异常
读未提交 允许,但不在PG中 可能 可能 可能
读已提交 不可能 可能 可能 可能
可重复读 不可能 不可能 允许,但不在PG中 可能
可序列化 不可能 不可能 不可能 不可能

3 总结

了解事务隔离对DBA非常重要,DBA可以根据业务的需求更改数据库的默认隔离级别,预期达到性能的最大化。

原文地址:https://www.cnblogs.com/easonbook/p/10990299.html

时间: 2024-10-11 11:04:20

关于postgresql中事务隔离的总结的相关文章

mysql中事务隔离级别可重复读说明

mysql中InnoDB引擎默认为可重复读的(REPEATABLE READ).修改隔离级别的方法,你可以在my.inf文件的[mysqld]中配置: transaction-isolation = {READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE} 用户可以用SET TRANSACTION语句改变单个会话或者所有新进连接的隔离级别.它的语法如下: SET [SESSION | GLOBAL] TRANSACT

mysql 4中事务隔离级别

SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的.低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销.Read Uncommitted(读取未提交内容) 在该隔离级别,所有事务都可以看到其他未提交事务的执行结果.本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少.读取未提交的数据,也被称之为脏读(Dirty Read).Read Committed(读取提交内容) 这是大多数数据库系统的默认隔离级别(但不是MySQL默认的).

SQL Server中锁与事务隔离级别

SQL Server中的锁分为两类: 共享锁 排它锁 锁的兼容性:事务间锁的相互影响称为锁的兼容性. 锁模式 是否可以持有排它锁 是否可以持有共享锁 已持有排它锁 否 否 已持有共享锁 否 是 SQL Server中可以锁定的资源包括:RID或键(行).页.对象(如表).数据库等等. 在试图修改数据(增删改)时,事务会请求数据资源的一个排它锁而不考虑事务的隔离级别.排它锁直到事务结束才会解除.对于单语句事务,语句执行完毕该事物就结束了:对于多语句事务,执行完COMMIT TRAN或者ROLLBA

mysql-Innodb事务隔离级别-repeatable read详解

http://blog.csdn.net/dong976209075/article/details/8802778 经验总结: Python使用MySQLdb数据库后,如使用多线程,每个线程创建一个db链接,然后再各自创建一个游标cursor,其中第一个线程读一个表中数据为空,第二个写入该表一条数据并提交,第一个线程再读该表数据将仍然无法读出.和多数据库的事务级别应该有关系:还可以在第一个读之前先插入一条,将能够读出第二个线程写入并提交过的数据. 转载自:http://blog.csdn.ne

Spring随笔 - 事务隔离级别

Spring提供5中事务隔离级别: ISOLATION_DEFAULT:使用数据库后端的默认隔离级别. ISOLATION_READ_UNCOMMITTED:允许读取尚未提交的数据变更.可能会导致脏读.幻读或者不可重复读. ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据.可以阻止脏读,但是幻读或者不可重复读仍有肯能发生. ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果是一致的.除非数据被本事务自己所修改,可以防止脏读和不可重复读,但

【转载】JDBC事务隔离级别

转自:http://blog.csdn.net/crow_feiyu/article/details/51305826 数据库并发事务可能出现的几种状态: 读脏:一个事务读取另外一个事务尚未提交的数据.如下图,线程thread1在事务中在time1时刻向库表中新增一条数据'test'并在time3时刻回滚数据:线程thread2在time2时刻读取,若thread2读取到'test',则为读脏. 不可重新读:其他事务的操作导致某个事务两次读取数据不一致.如下图,线程thread1在事务中time

MySQL的四种事务隔离级别

一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样.也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位. 2.一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 .比如A向B转账,不可能A扣了钱,B却没收到. 3.隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不

MySQL的四种事务隔离级别【转】

本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样.也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位.  2.一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 .比如A向B转账,不可能A扣了钱

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

前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所以对于加锁的处理,可以说就是数据库对于事务处理的精髓所在.这里通过分析MySQL中InnoDB引擎的加锁机制,来抛砖引玉,让读者更好的理解,在事务处理中数据库到底做了什么. #一次封锁or两段锁? 因为有大量的并发访问,为了预防死锁,一般应用中推荐使用一次封锁法,就是在方法的开始阶段,已经预先知道