数据库 一致性读&&当前读

今天小伙伴问了一个sql的问题:

  update t set status=2 where id in(select id from t where status=1)

这个sql,在并发的情况下,会不会有问题?

假设:下面的讨论,数据库的事务隔离级别是read_committed

其实这个可以很容易测试一下,得出结论:存在丢失更新的问题。

先来理解两个概念:

1. 一致性读

  当前的数据库产品级别都实现了多版本一致性,即MVCC,那么有了MVCC,数据库实现了读写互不阻塞的效果。
但为了达到read_committed事务隔离级别,以及语句级的读一致性,select语句需要构建一个版本,数据库会根据一个版本号,来构建。
比如oracle使用scn号,为了构建这个版本,产生的读,称为一致性读。

2. 当前读
  数据库在写入的过程中,比如update,因为要验证constraint,冲突等,需要读到当前数据,包括没有commit的事务,这样就产生了当前读。

oracle中英文解释:

  一致性读:  Consistent read

  当前读:  Current read

而上面的这个语句,就存在了两种读取。

  select: 会进行一致性读,
  update:会进行当前读。

而在并发的情况下: 第二个update可能因为更新到同一行(其他更新本行的事务未提交),而被阻塞。
当另一个事务提交后,第二个update会再次构建当前读,会把status从2再次更新成2.

如何避免:

1. 更改语句:
    update t set status=2 where id in(select id from t where status=1) and status=1;

2. 调整事务的隔离级别

数据库 一致性读&&当前读

时间: 2024-10-08 06:02:07

数据库 一致性读&&当前读的相关文章

MySQL锁类型(一致性是非锁定读、自增和外键)

1.一致性的非锁定读 一致性的非锁定读(consistent nonlocking read)是指InnoDB存储引擎通过行多版本控制(multi versionning)的方式来读取当前执行时间数据库中行的数据.如果读取的行正在执行DELETE或UPDATE操作,这时读取操作不会因此去等待行上锁的释放,相反地,InnoDB存储引擎会去读取行地一个快照数据. 快照数据是指该行地之前版本地数据,该实现是通过undo段来完成.而undo用来在事务中回滚数据,因此快照数据本身是没有额外地开销.此外,读

数据库一致性理解

本文摘自知乎: https://www.zhihu.com/question/31346392/answer/51924208 原子性:记录之前的版本,允许回滚 一致性:事务开始和结束之间的中间状态不会被其他事务看到 隔离性:适当的破坏一致性来提升性能与并行度 例如:最终一致~=读未提交. 持久性:每一次的事务提交后就会保证不会丢失 ----------------------------------------------------------------------------------

【58沈剑架构系列】缓存与数据库一致性保证

本文主要讨论这么几个问题: (1)啥时候数据库和缓存中的数据会不一致 (2)不一致优化思路 (3)如何保证数据库与缓存的一致性 一.需求缘起 上一篇<缓存架构设计细节二三事>(点击查看)引起了广泛的讨论,其中有一个结论:当数据发生变化时,“先淘汰缓存,再修改数据库”这个点是大家讨论的最多的. 上篇文章得出这个结论的依据是,由于操作缓存与操作数据库不是原子的,非常有可能出现执行失败. 假设先写数据库,再淘汰缓存:第一步写数据库操作成功,第二步淘汰缓存失败,则会出现DB中是新数据,Cache中是旧

分布式缓存数据库一致性问题

缓存和数据库一致性问题,有很多解决方案,没有最完美的方案,只有适合自身业务的尽可能完美的方案. 缓存由于其高并发和高性能的特征,已经在项目中被广泛应用. 查询时一般先查询缓存,如果缓存命中的话,那么直接将数据返回. 如果缓存中没有数据(如失效,或者根本没设置数据),那么,应用程序先从数据库中查询数据,如果不为空,则将数据放在缓存中. 那么更新时,怎么处理缓存和数据库呢?先更新数据库后更新缓存?先更新数据库后更新缓存?或者先淘汰缓存后更新数据库? 为什么没有先更新缓存后更新数据库? 1):如果更新

读一读Scktsrvr.exe的源程序

使用DELPHI做多层开发的朋友们都应该对Scktsrvr.exe这个程序不陌生的,Borland公司在DELPHI中给出了它的源代码.这是一个900来行的程序,程序不算长,现在我只选其中部分仔细读一读.走的线路大致是,从服务器接到客户端连接,处理客户端的一个请求(这儿选了客户端向服务器发出的'取应用服务器列表'请求) 服务器接受了客户端连接后,因为ServerSocket采用的是阻塞模式,服务器执行了下面这个线程来服务客户端: //SCKTMAIN.PAS PRocedure TSocketD

[No000060]冷读热读:读书九问

兵无常势,水无常形,读书亦无法.彼之砒霜,我之佳肴.然读书无法却有道.你我都是使用同一颗大脑在读书.这颗大脑受制于那千千万万年以来,星辰起落,狩猎采集,演化大道. Q1:读物如何分级? 坏书.可用的书.力作.杰作与神作. 世人皆知精读略读,却不知冷读热读.你的大脑习惯用数字来锚定一切.既然都是书这种载体,价格.页数成了你的挑选标准.你总是习惯赋予神作与垃圾读物一样的阅读时间.须不知,人有好坏,书有高下.因此爱书之人均有自己的读物分级系统.我将图书分为:坏书.可用的书.力作.杰作与神作.多数图书,

SQL Server逻辑读-预读-物理读

SQL Server逻辑读-预读-物理读    SQL Server 存储数据的方式        1.页是最小的操作单元,也就是说从磁盘读取数据库的时候最少读取一页,每一页的大小是8KB,SQL SERVER对于页的读取是原子性,要么读完一页,要么完全不读,不会有中间状态 2.区是8个连续的页组成的,区是最小的分配单元,当需要空间时最少分配一个区的空间. 看图说话,两个表的结构完全一样,一个插入四条数据,另一个插入100条数据,结果大小都为0.008: SQL SERVER一页的总大小为:8K

Hadoop源码学习笔记(1) ——第二季开始——找到Main函数及读一读Configure类

Hadoop源码学习笔记(1) ——找到Main函数及读一读Configure类 前面在第一季中,我们简单地研究了下Hadoop是什么,怎么用.在这开源的大牛作品的诱惑下,接下来我们要研究一下它是如何实现的. 提前申明,本人是一直搞.net的,对java略为生疏,所以在学习该作品时,会时不时插入对java的学习,到时也会摆一些上来,包括一下设计模式之类的.欢迎高手指正. 整个学习过程,我们主要通过eclipse来学习,之前已经讲过如何在eclipse中搭建调试环境,这里就不多述了. 在之前源码初

[20140804] 疑似存储上线导致数据库一致性问题

背景: 同一个存储设备提供了2块存储,1块已经在使用 a,另外一块没有使用b. 疑似: 当b初始化,上线之后,导致在a存储的数据库文件出现一致性问题. 解决方法: 幸好有数据库镜像,打算切换数据库镜像,然后备份数据库镜像,还原到原来的master. 然后创建数据库镜像,在切换到原来的master上. [20140804] 疑似存储上线导致数据库一致性问题,布布扣,bubuko.com