专栏首页木可大大脏读、不可重复读和幻读现象

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

对于软件开发人员来说,有时候我们需要面对瞬时海量的并发请求,例如阿里双十一等活动,当处理并发流程时需要我们通过各种机制保持数据一致性,其中,最有效的一种机制就是锁机制。而对于数据库管理人员来说,并发问题同样存在。并发问题的本质在于一条逻辑代码在机器层面可能需要几条指令来完成,也就是说这条逻辑代码可能在多个机器周期内完成,如果在顺时执行时这样执行是不会存在问题的,而在并发执行时就会出现数据不一致的情况。这种最小的逻辑指令对应到数据库中就是事务,事务包含原子性(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),作者:老柯

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

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

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 漫谈计算机架构

    一说到计算机架构(Computer Architecture),大家可能会有疑问:计算机架构到底是个什么东西?引用维基百科对计算机架构的定义:

    木可大大
  • RAID技术

    RAID 的两个关键目标是提高数据可靠性和 I/O 性能。磁盘阵列中,数据分散在多个磁盘中,然而对于计算机系统来说,就像一个单独的磁盘。通过把相同数据同时写入到...

    木可大大
  • 漫谈计算机架构

    一说到计算机架构(Computer Architecture),大家可能会有疑问:计算机架构到底是个什么东西?引用维基百科对计算机架构的定义:

    木可大大
  • SVN工具分析

    寄语:虽然现在很多项目都使用GIT进行版本管理,但是SVN还有使用的,这篇文档压箱底了好久,思虑再三,还是发出来吧,说不定能帮助到别人。

    Sky_Mao
  • Parallelism Vs Concurrency

    这是两个英文解释边界都很模糊的单词,翻译到中文里就更让人满头雾水了。网友对这两个词的解释也是各执一词,网友在Stack Overflow 上也问过这个问题Wha...

    Dylan Liu
  • ECshop 快捷登录插件 支持QQ 支付宝 微博

    亲自测试可以使用,分享给大家。(承接各种EcShop改版,二次开发等相关项目 QQ:377898650) 安装的时候按照里面说明。安装即可。 代码下载:http...

    Java中文社群_老王
  • U盘安装linux发行版 原

    Manjaro是一款基于Arch Linux、对用户友好、全球排名第1的Linux发行版。(排名数据源于DistroWatch,统计日期2018.03.02,时...

    wuweixiang
  • 简单端口映射、转发、重定向工具-Rinetd

    Rinetd是为在一个Unix和Linux操作系统中为重定向传输控制协议(TCP)连接的一个工具。Rinetd是单一过程的服务器,它处理任何数量的连接到在配置文...

    py3study
  • Centos7安装轻量级TCP转发工具rinetd注册为服务的正确姿势 并设置开机自启 实践笔记 自用

    cookily
  • 你还在用U盘傻瓜式地拷贝文件吗?如何跨操作系统共享文件?

    本文探讨macOS、Linux、Windows三种操作系统两两之间的文件共享方式,根据数学中的排列组合知识可知,总共有六种两两组合方式。

    城市中的游牧民族

扫码关注云+社区

领取腾讯云代金券