1、脏读

脏页只是在缓冲池中已经修改的页但是没有刷新到磁盘中,即数据库实例内存中的页和磁盘中的页事不一致的,当然在刷新到磁盘之前,日志都已经被写入到了重做日志文件中,而所谓的脏数据是指事务对缓冲池中行记录的修改,但并没有被提交

对于脏页的读取,是非常正常的。脏页是因为数据库实例内存和磁盘异步造成的,这并不影响数据的一致性(或者说两者最终会达到一致性,当脏页刷新回到磁盘中)。并且因为脏页的刷新时异步的,不影响数据库的可用性,带来了性能的提高

脏数据就截然不同,脏数据是未提交的数据,如果读到了脏数据,即一个事务可以读到另一个事务中未提交的数据,则显然违反了数据库的隔离性

脏读是值在不同的事务下,当前事务可以读到另外事务未提交的数据,简单来说就是可以读到脏数据。

表t中的事务隔离级别有默认的RR改成READ UNCOMMITED ,因此在会话A中,在事务未提交的前提下,会话B中的两次SELECT操作取得了不同的结果,并且2这条记录是在会话A中并未提交的数据,即产生了脏读,违反了事务隔离性

脏读隔离看似毫无用处,但在一些比较特殊的情况下还是可以将事务隔离级别设置成READ UNCOMMITTED。例如replication环境中的slave节点,并且该slave的查询不需要特别精确的返回值

2、不可重复读

不可重复读是指在一个事务内多次读取同一数据集合,在这个事务还没有结束时,另外一个事务也访问该同一数据集合,并做了一些DML操作,因此,在第一个事务中两次数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能不一样。这样就发生了在一个事务内两次读到的数据不一样的情况,称为不可重复读

不可重复读和脏读的区别:脏读是读到未提交的数据,而不可重复读读到的是已经提交的数据,但是其违反了数据库一致性的要求

在会话A中开始一个事务,第一次读到的1,另一个会话B中开始另一个事务,插入一条2的记录,在没有提交之前,对会话A中的事务进行再次读取是,读到的记录还是1,没有发生脏读的现象,但在会话B中事务提交后,在会话A中的事务进行读取时,这是读到的是1和2这两条记录,这个例子的前提是,会话A和会话B的事务隔离级别是RC

一般来说,不可重复读是可以接收的,因为其读到的是已经提交的数据,本身不会带来很大的问题,因此很多数据库产商将其事务隔离级别默认设置成RC,在这种隔离级别下允许不可重复读的现象

在InnoDB存储引擎中,通过Next-Key Lock算法来避免不可重复读的问题,在MySQL官方文档将不可重复读的问题定义为Phantom Problem,即幻像问题。在Next-Key Lock算法下,对于索引的扫描,不仅是锁住扫描的索引,还是锁住这些索引覆盖的范围gap,因此这个范围内的插入都是不允许的,这样就避免了另外的事务在这个范围内插入数据导致不可重复读的问题。因此InnoDB存储引擎的默认事务隔离级别是RR,采用Next-Key Lock算法,避免不可重复读的现象

3、丢失更新

丢失更新是另一个锁导致的问题,简单来说其就是一个事务的更新操作会被另一个事务的更新操作锁覆盖,从而导致数据的不一致,例如
事务T1将行记录r更新为v1,但是事务T1并未提交
与此同时,事务T2将行记录r更新为v2,事务T2未提交
事务T1提交
事务T2提交

但是在当前数据库的任何隔离级别下,都不会导致数据库理论上的丢失更新问题。这是因为,即使是READ UNCOMMITTED的事务隔离级别,对于行的DML操作,需要对行或者其他粗粒度级别的对象加锁,因此在上述步骤B中,事务T2并不能对行记录r进行更新操作,其余被阻塞,直到事务T1提交

虽然数据库能阻止丢失更新问题的产生,但是在生产应用中还有另一个逻辑意义的丢失更新问题呢,而导致该问题并不是因为数据库本身的问题。实际上,在所有多用户计算机系统环境下都有可能产生这个问题。简单来说,出现下面的情况,就会发生丢失更新

A.    事务T1查询一行数据,放入本地内存,并显示给一个终端用户User1
B. 事务T2也查询该行数据,并将取得的数据显示给终端用户User2
C. User1修改这行的记录,更新数据库并提交
D. User2修改这行的记录,更新数据库并提交

显然,这个过程中用户User1的修改更新操作会丢失了,而这可能会导致一个恐怖的结果,设想银行发生丢失更新的现象。例如一个用户账号有10 000人民币,他用两个网上银行的客户端分别进行转账操作。第一次转账9000,因为网络和数据的关系,这需要等待,但这是用户操作另一个网上银行客户端,转账1元,如果这两笔操作都成功,用户的余额应该是9999,第一次转的9000并没有得到更新,但是在转账的另一个账户却受到了这9000,这导致的结果是钱变多,而账不平。也许读者会说,不对,我的网银是USB Key的,不会发生这种情况,是的,通过Usb key登录也许可以解决这个问题,但是最重要的是在数据库层解决这个问题,避免任何可能发生更新的情况

要避免丢失更新发生,需要将事务在这种情况下操作变成串行化,而不是并行操作,即在上述步骤的1中,对用户读取的记录加一个排他X锁,同样,在步骤2的操作过程中,用户同样需要加一个排他X锁,通过这种方式,步骤2就必须等待1和步骤3的完成,最后完成步骤4

MySQL中锁问题的更多相关文章

  1. MySQL中锁详解(行锁、表锁、页锁、悲观锁、乐观锁等)

    原文地址:http://blog.csdn.net/mysteryhaohao/article/details/51669741 锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是 ...

  2. MySQL中锁的类型

    InnoDB存储引擎实现了一下两种标准的行级锁: 共享锁S LOCK 允许事务读一行数据 排他锁 X LOCK 允许事务删除或更新一行数据 如果是一个事务T1斤获得了行r的共享锁,那么另外一个事务T2 ...

  3. MySQL中锁详解(行锁、表锁、页锁、悲观锁、乐观锁等)

    悲观锁: 顾名思义,很悲观,就是每次拿数据的时候都认为别的线程会修改数据,所以在每次拿的时候都会给数据上锁.上锁之后,当别的线程想要拿数据时,就会阻塞,直到给数据上锁的线程将事务提交或者回滚.传统的关 ...

  4. MySql 中锁的定义

    行级锁,一般是指排它锁,即被锁定行不可进行修改,删除,只可以被其他会话select.行级锁之前需要先加表结构共享锁. 表级锁,一般是指表结构共享锁锁,是不可对该表执行DDL操作,但对DML操作都不限制 ...

  5. 【大厂面试05期】说一说你对MySQL中锁的了解?

    这是我总结的一个表格,是本文中涉及到的锁(因为篇幅有限就没有包括自增锁) 加锁范围 名称 用法 数据库级 全局读锁 执行Flush tables with read lock命令各整个库接加一个读锁, ...

  6. mysql的锁与事务

    1. MySQL中的事物 1.InnoDB事务原理 1. 事务(Transaction)是数据库区别于文件系统的重要特性之一,事务会把数据库从一种一致性状态转换为另一种一致性状态. 2. 在数据库提交 ...

  7. [数据库事务与锁]详解六: MySQL中的共享锁与排他锁

    注明: 本文转载自http://www.hollischuang.com/archives/923 在MySQL中的行级锁,表级锁,页级锁中介绍过,行级锁是Mysql中锁定粒度最细的一种锁,行级锁能大 ...

  8. [数据库事务与锁]详解五: MySQL中的行级锁,表级锁,页级锁

    注明: 本文转载自http://www.hollischuang.com/archives/914 在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的 ...

  9. MySQL中select * for update锁表的范围

    MySQL中select * for update锁表的问题 由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例 ...

随机推荐

  1. python 在Windows中描述路径时出现的问题

    问题的根本:windows读取文件可以用\,但在字符串里面\被作为转义字符使用,   python在描述路径时有两种方式: 'd:\\a.txt',转义的方式 r'd:\a.txt',声明字符串不需要 ...

  2. angular4 radio checkbox 有用

    <span *ngFor="let op of [{'id':'a','text':'11'},{'id':'b','text':'2222'},{'id':'cc','text':' ...

  3. web info

    http://blog.csdn.net/qq_24473141/article/details/51363662 http://blog.sina.com.cn/s/blog_8e392fc2010 ...

  4. java - day06 - arraycopy

    package day05; import java.util.Arrays; import java.util.Random; /* * 附:如果需要使用引用类,如Random类的方法, * 需要新 ...

  5. eclipse 断点类别

    行断点 行断点位于一般方法内,双击代码行左边就可以设置行断点: 行断点可以设置条件,右键断点-properties: 1设置效果是第几次到达时暂停,图中所示是当第三次到达时暂停 2是开启条件断点 3是 ...

  6. Android中makfile的随记

    什么是makefile?也许非常多Winodws的程序员都不知道这个东西,由于那些Windows的IDE都为你做了这个工作,但我认为要作一个好的Android底层程序员. makefile还是要懂. ...

  7. IOS设计模式的六大设计原则之迪米特法则(LOD,Law Of Demeter)

    定义 狭义的迪米特法则定义:也叫最少知识原则(LKP,Least Knowledge Principle).如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用.如果其中的一个类需要调用 ...

  8. Editing a Book UVA - 11212 IDA*

    You have n equal-length paragraphs numbered 1 to n . Now you want to arrange them in the order of 1 ...

  9. zabbix 监控如下内容

    我们使用zabbix做了如下的监控: 1.硬件监控. 通过SNMP来进行路由器交换机的监控(这些可以跟一些厂商沟通来了解如何做). 服务器的温度以及其他,可以通过IPMI来实现.当然如果没有硬件全都是 ...

  10. 【转】 详细介绍windows下使用python pylot进行网站压力测试

    windows下使用python进行网站压力测试,有两个必不可少的程序需要安装,一个是python,另一个是pylot.python是一个安装软件,用来运行python程序,而pylot则是pytho ...