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

MySQL事务(脏读、不可重复读、幻读)

作者头像
用户7353950
发布2022-05-10 18:37:25
1.1K0
发布2022-05-10 18:37:25
举报
文章被收录于专栏:IT技术订阅

1. 什么是事务?

  是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元);

2.事务的四大特性ACID

  一个事务往往具有一下特性:

原子性(ATOMICITY):   一个事务要被完全的无二义性的做完或撤消。在任何操作出现一个错误的情况下,构成事务的所有操作的效果必须被撤消,数据应被回滚到以前的状态。

一致性(CONSISTENCY):

  一个事务应该保护所有定义在数据上的不变的属性(例如完整性约束)。在完成了一个成功的事务时,数据应处于一致的状态。换句话说,一个事务应该把系统从一个一致-状态转换到另一个一致状态。举个例子,在关系数据库的情况下, 一个一致的事务将保护定义在数据上的所有完整性约束。

隔离性(ISOLATION):

  在同一个环境中可能有多个事务并发执行,而每个事务都应表现为独立执行。串行的执行一系列事务的效果应该同于并发的执行它们。这要求两件事:

  在一个事务执行过程中,数据的中间的(可能不一致)状态不应该被暴露给所有的其他事务。   两个并发的事务应该不能操作同一项数据。数据库管理系统通常使用锁来实现这个特征。

持久性(DURABILITY):   一个被完成的事务的效果应该是持久的。

3.创建事务的SQL语法

隐式事务:事务没有明显的开启或者结束的标志,在mysql中,默认是开启自动提交的

代码语言:javascript
复制
SHOW @@autocommit;

  所以针对SELECT、UPDATE、DELETE、INSERT等DQL及DML语句的执行,mysql会自动提交该事务,如果关闭就需要手动提交或者回滚来完成操作。

显式事务:与隐式事务想反,有明显的开启或结束标志。

代码语言:javascript
复制
SET autocommit=0
[START TRANSACTION]  # 可选的语句
[DELETE | UPDATE | INSERT | SELECT ]  # DML、DQL操作
[COMMIT | ROLLBACK];  #提交或者回滚

  可以看出,在事务未结束之前,操作是有效的且更改了数据实体,那么试想一下,如果这是有多个事务参与, 肯定会出现各种各样的数据不统一的情况,这就类似多个线程在没有锁的情况下修改同一个全局变量。

  显式事务:回滚点的使用(setpoint)

代码语言:javascript
复制
SET AUTOCOMMIT=0;
START TRANSACTION;
[DELETE | UPDATE | INSERT | SELECT];  #回滚时要执行提交的部分
SAVEPOINT a;  # 设置回滚点,且变量名为a
[DELETE | UPDATE | INSERT | SELECT];  #回滚时不执行提交的部分
ROLLBACK TO a;  # 回滚时与ROLLBACK TO搭配使用

  可以发现在回滚点以前的数据实体被删除、之后的数据实体因为回滚而被撤销操作。

注意:在事务中使用truncate时,就算rollback也会清空整张表

4.多个事务在不同事务隔离级别下的并发问题

  在mysql下事务的隔离级别有四种且由低到高依次为Read uncommittedRead committedRepeatable read (默认)、Serializable ,这四个级别中的后三个级别可以逐个解决脏读不可重复读幻读这几类问题

  1. 脏读的情况:对于两个事务T1与T2,T1读取了已经被T2更新但是还没有提交的字段之后,若此时T2回滚,T1读取的内容就是临时并且无效的

  开启两个mysql客户端,并创建一张测试表transaction

  更改默认隔离级别REPEATABLE READ为READ UNCOMMITTED

代码语言:javascript
复制
SELECT @@tx_isolation; #查询隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; # 更改隔离级别

  两个客户端同时开启事务,其中一个事务做UPDATE操作,另一个事务做SELECT

  若此时黑色背景的客户端进行回滚,则白色背景的客户端读取的数据就是临时并且无效的。即脏读。

2. 不可重复读: 对于两个事务T1和T2,T1读取了一个字段,然后T2更新了该字段并提交之后,T1再次提取同一个字段,值便不相等了。

  重复读取的结果不一致的情况发生。

3. 幻读: 对于两个事务T1、T2,T1从表中读取数据,然后T2进行了INSERT操作并提交,当T1'再次读取的时候,结果不一致的情况发生。

5. 不同隔离级别所解决的事务并发问题

脏读

不可重复读

幻读

READ UNCOMMITTED

1

1

1

READ COMMITTED

0

1

1

REPEATABLE READ

0

0

1

SERIALIZABLE

0

0

0

READ UNCOMMITTED级别不做演示,其隔离性最低,会出现脏读、不可重复读、幻读等所有情况。

READ COMMITTED级别能够避免脏读,下面来进行演示:

1.避免脏读(一个事务读取到另一个事务未提交的数据)

2. 无法避免重复读(一个事务读取到另一个事务已经提交的数据)

REPEATABLE READ避免不可重复读的情况发生,下面来看演示: 1. 避免不可重复读(一个事务读取到另一个事务已经提交的数据)

2. 无法避免幻读(一个事务多次查询整表数据,由于其他事务新增(删除)记录造成多次查询的记录条数不同(一个事务读取到另一个事务已经提交的数据))

SERIALIZABLE避免幻读情况,阻塞方式

  可以看出,serializable级别就类似加锁的方式,同一时刻支持多个事务并发,但是针对DML(UPDATE\INSERT\DELETE)操作时,当前发起操作的事务会被阻塞,直到其他事务commit或者rollback才会继续执行事务语句。可见效率十分低下。

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

本文分享自 IT技术订阅 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 什么是事务?
  • 2.事务的四大特性ACID
  • 3.创建事务的SQL语法
  • 4.多个事务在不同事务隔离级别下的并发问题
  • 5. 不同隔离级别所解决的事务并发问题
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档