前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >脏读、不可重复读和幻读现象

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

作者头像
木可大大
发布2018-07-25 15:11:32
9460
发布2018-07-25 15:11:32
举报
文章被收录于专栏:木可大大木可大大

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

Read uncommitted(读未提交)

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

实验-> 脏读现象
  • 查看隔离级别
代码语言:javascript
复制
show variables like 'tx_iso%';
  • 修改隔离级别
代码语言:javascript
复制
mysql> set tx_isolation='READ-UNCOMMITTED';

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

代码语言:javascript
复制
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
  • 创建表
代码语言:javascript
复制
create table test(int id);//典型的错误,可以和java 类比create table test(id int);//正确写法

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

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

Read Committed(读已提交)

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

实验-> 不可重复读现象
  • 清除test数据
代码语言:javascript
复制
truncate table test;

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

Repeatable Read(可重复读)

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

实验-> 可重复读
代码语言:javascript
复制
session1        session2
begin;          begin;

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

insert;

commit;

                 select;

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

代码语言:javascript
复制
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并发控制退化为基于锁的并发控制。不区分快照读与当前读,所有的读操作均为当前读。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-05-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 木可大大 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实验-> 脏读现象
  • 实验-> 不可重复读现象
  • 实验-> 可重复读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档