脏读、不可重复读和幻读现象

对于软件开发人员来说,有时候我们需要面对瞬时海量的并发请求,例如阿里双十一等活动,当处理并发流程时需要我们通过各种机制保持数据一致性,其中,最有效的一种机制就是锁机制。而对于数据库管理人员来说,并发问题同样存在。并发问题的本质在于一条逻辑代码在机器层面可能需要几条指令来完成,也就是说这条逻辑代码可能在多个机器周期内完成,如果在顺时执行时这样执行是不会存在问题的,而在并发执行时就会出现数据不一致的情况。这种最小的逻辑指令对应到数据库中就是事务,事务包含原子性(Atomicity)、一致性(Consistency)、一致性(Consistency)和持久性(Durability)。而由于一个事务在机器层面可能需要几条指令完成,这也意味着它在并发时会出现如下问题:脏读、不可重复读和幻读,下面以MySQL为例详细介绍在什么情况下可能会出现上述问题。

Read uncommitted(读未提交)

此事务隔离级别会出现脏读现象*(事务的修改,即使没有提交,其他事务也能看的到),不建议在生产环境中去使用。

实验-> 脏读现象
  • 查看隔离级别
show variables like 'tx_iso%';
  • 修改隔离级别
mysql> set tx_isolation='READ-UNCOMMITTED';

注意:READ-UNCOMMITTED是字符串,如果不使用双引号,就会报错,错误信息如下:

set tx_isolation=READ-UNCOMMITTED;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'READ-UNCOMMITTED' at line 1
  • 创建表
create table test(int id);//典型的错误,可以和java 类比create table test(id int);//正确写法

session1中新增一条数据,但是没有提交,可以session2却可以查询到session这条最新数据。

注意:我们需要手动开启事务(begin)和提交事务(commit),不然MySQL会自动提交事务。

Read Committed(读已提交)

针对当前读,RC隔离级别保证对读取到的记录加锁(记录锁),存在不可重复读现象(在一个事务内,多次读取,会读取到不同的数据)。

实验-> 不可重复读现象
  • 清除test数据
truncate table test;

我们发现session2中执行两次select * from test会出现不同的结果,这就是不可重复读现象。

Repeatable Read(可重复读)

这是MySQL默认隔离级别,解决不可重复读,但是还会出现存在幻读现象。幻读现象就是说当某个会话对某个数据进行修改并提交,而其他会话读取这个数据并不是最新的值。

实验-> 可重复读
session1        session2
begin;          begin;

                select ;//获得一个时间点快照,在表记录中的每一个行都会有trx_id,以后每次查询,都会查询比这个trx_id小于等于的值

insert;

commit;

                 select;

MySQL通过MVCC(解决读写并发问题)和间隙锁(解决写写并发问题)来解决幻读,Repetable Read违反了隔离性,ACID中对隔离性的定义如下:

The isolation property ensures that the concurrent execution of transactions results in a system state that would be obtained if transactions were executed sequentially, i.e., one after the other. Providing isolation is the main goal of concurrency control. Depending on the concurrency control method (i.e., if it uses strict - as opposed to relaxed - serializability), the effects of an incomplete transaction might not even be visible to another transaction

大概意思:一个没有提交的事务对其他事务是不可见的,而提交过的事务对其他事务是可见的。但是Repeatable Read中提交的事务对其他事务是不可见的,显然违反了隔离性。

Serializable(串行化)

串行化解决了脏读、不可重复读、幻读现象,但是效率会比较低下。从MVCC并发控制退化为基于锁的并发控制。不区分快照读与当前读,所有的读操作均为当前读。

原文发布于微信公众号 - 木可大大(mukedd)

原文发表时间:2018-05-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小白安全

Janus高危漏洞深度分析

一、背景介绍 近日,Android平台被爆出“核弹级”漏洞Janus(CVE-2017-13156),该漏洞允许攻击者任意修改Android应用中的代码...

36690
来自专栏LhWorld哥陪你聊算法

【Spark篇】---Spark中Shuffle文件的寻址

Spark中Shuffle文件的寻址是一个文件底层的管理机制,所以还是有必要了解一下的。

14950
来自专栏PingCAP的专栏

使用 Ansible 安装部署 TiDB

多机部署 TiDB 太繁琐?快来尝试我们的 TiDB 一键安装吧。本文介绍基于 Ansible Playbook 实现 TiDB 和监控组件的自动化安装和配置,...

1.5K00
来自专栏文渊之博

关于事务的隔离级别和处理机制的理解

     前几日有一个猎头公司的面试,其中问道我事务隔离这块的知识点,猛一问真是想不起来啊,顿感羞愧啊,回来专门总结一下这方面的知识来夯实一下之前的知识体系,也...

17880
来自专栏Java技术栈

Java提升篇-事务隔离级别和传播机制

问题的提出 为了保证并发操作数据的正确性及一致性,SQL规范于1992年提出了数据库事务隔离级别。 事务隔离级别分类 事务隔离级别由低往高可分为以下几类 REA...

39350
来自专栏武培轩的专栏

《从Paxos到Zookeeper:分布式一致性原理与实践》第一章读书笔记

第一章主要介绍了计算机系统从集中式向分布式系统演变过程中面临的挑战,并简要介绍了ACID、CAP和BASE等经典分布式理论,主要包含以下内容:

12910
来自专栏软件开发

WebSocket与消息推送

B/S结构的软件项目中有时客户端需要实时的获得服务器消息,但默认HTTP协议只支持请求响应模式,这样做可以简化Web服务器,减少服务器的负担,加快响应速度,因为...

89650
来自专栏菜鸟程序员

Janus高危漏洞深度分析

18430
来自专栏java达人

关于mysql锁的两个例子

版本:mysql5.5.52 存储引擎:InnoDB 隔离级别:READ-COMMITTED 示例一: 事务1:左图 事务2:右图 1、 ? 事务...

22980
来自专栏三丰SanFeng

Linux进程间通信(一) - 管道

管道(pipe) 普通的Linux shell都允许重定向,而重定向使用的就是管道。 例如:ps | grep vsftpd .管道是单向的、先进先出的、无结构...

27070

扫码关注云+社区

领取腾讯云代金券