linuxsir首页 LinuxSir.Org | Linux、BSD、Solaris、Unix | 开源传万世,因有我参与欢迎您!
网站首页 | 设为首页 | 加入收藏
您所在的位置:主页 > Linux数据库 >

MySQL中的事务隔离级别

时间:2019-11-25  来源:未知  作者:admin666

事务是逻辑上的一组操作,要么都执行,要么都不执行。

事务最经典的、经常被拿出来说的例子就是转账了。假如小花要给小白转账1000元,这个转账会涉及到两个关键操作就是:将小花的余额-1000,将小白的余额+1000。但是万一在这两个操作之间突然出现了错误,比如银行系统突然断电,或突然宕机崩溃,都可能会导致小花的余额-1000之后,小白的余额却没有+1000,这样小花和小白就都不开心了。事务就是为了保证这两个关键操作要么都成功,要么都要失败的一个机制,都成功也就完成了转账,都失败也不会造成小花的损失。

事务的特性

事务是有四个特性(ACID)的,分别是原子性、一致性、隔离性和持久性。

原子性(Atomity): 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用。

一致性(Consistency): 执行事务的前后,数据保持一致。

隔离性(Isolation): 并发访问数据库时,一个用户的事务不能被其他事务所干扰,各个并发事务对于数据库来说都是独立的。

持久性(Durable):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

并发事务带来的问题

在典型的应用程序中,如果是多个事务并发运行,经常会出现多个事务操作相同的数据来完成各自的任务(多个用户对统一数据进行操作)的场景。

虽然并发是必须的,但却可能会导致以下的问题。

1.脏读(Dirty Read)

当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,而这个数据可能最后并不会被提交到数据库中,那么另外一个事务读到的这个数据是【脏数据】,依据【脏数据】所做的操作就可能是不正确的。

2.丢失修改(Lost to Modify)

在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样就可能会导致第一个事务内的修改结果被丢失,因为实际上最终生效的修改是第二个事务做的修改,这就是丢失修改。例如,事务1读取了某表中的数据A=21,事务2也读取的是A=21,当事务1修改了A=A-1,事务2也修改了A=A-1,可是最终的结果是A=20,事务1的修改被丢失。

3.不可重复读(Unrepeatableread)

不可重复读指的是在一个事务内多次读取同一数据,这前后两次读取的数据却不一致的情况。因为在这个事务还没有结束时,可能会有另一个事务也访问该数据,可能会造成在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据不一样的问题。在同一个事务内两次读到的数据不一样的情况,被称为不可重复读。

4.幻读(Phantom Read)

幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。

不可重复度和幻读的区别

不可重复读的重点是修改,强调的是记录的状态,比如记录中的一些属性;幻读的重点在于新增或者删除,强调的是记录的数量,比如多了几条记录或少了几条记录。

不可重复读的例子(同样的条件,你读取过的数据,再次读取出来发现值不一样了):事务1中的A先生读取自己的余额为1000的操作还没完成,事务2中的B先生就修改了A先生的余额为2000,导致A先生再次读自己的余额时余额变为了2000,这就是不可重复读。

幻读的例子(同样的条件,第1次和第2次读出来的记录数不一样):假如工资单表中工资大于1W的有24人,事务1读取了所有工资大于1W的人,共查到24条记录,而这时事务2又插入了一条工资大于1W的记录,事务1再次读取时查到的记录就变为了25条,这样就导致了幻读。

事务隔离级别

在的SQL标准中定义了四个隔离级别,分别是读取未提交、读取已提交、可重读和可串行化。

读取未提交(READ-UNCOMMITTED):最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。

读取已提交(READ-COMMITTED):允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

可重读(REPEATABLE-READ):对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

可串行化(SERIALIZABLE):最高的隔离级别,完全服从ACID四个特性。在这个隔离级别下,所有的事务是依次逐个执行,严格保证事务之间完全不可能产生干扰。这就意味着,这个级别可以有效防止脏读、不可重复读以及幻读。

MySQL中的InnoDB存储引擎的默认使用的隔离级别是REPEATABLE-READ(可重读)。

SELECT @@tx_isolation;

通过上面的命令可以查询出当前MySQL使用的隔离级别。

这里需要注意,MySQL对隔离级别的实现与SQL标准不同的地方在于InnoDB存储引擎在REPEATABLE-READ(可重读)事务隔离级别下使用的是Next-Key Lock锁算法,因此可以避免幻读的产生,这与其他数据库系统(如 SQL Server)是不同的。这也意味着InnoDB存储引擎的默认隔离级别REPEATABLE-READ(可重读)已经可以完全保证事务的隔离性要求,即达到了SQL标准的SERIALIZABLE(可串行化)隔离级别。

我们知道,数据库的隔离级别通常是使用锁来实现的。隔离级别越低,事务请求的锁也就越少,造成的性能损失也就越低,数据库响应也就越快,所以大部分数据库系统的隔离级别都是READ-COMMITTED(读取已提交内容)。但是你要知道的是,MySQL的InnoDB存储引擎默认使用的REPEATABLE-READ(可重读)并不会有任何性能损失(真的吗),因为MySQL做了一些相应的优化。另外,InnoDB存储引擎在分布式事务的情况下一般会用到SERIALIZABLE(可串行化)隔离级别,这是场景的特殊性决定的。

事务相关命令

在MySQL命令行的默认配置中,事务都是自动提交的,即执行SQL语句后就会马上执行COMMIT操作。

我们可以通过下面的命令来设置隔离级别。

SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]

另外还有一些并发控制语句,也是开发中经常会使用到的。

START TARNSACTION | BEGIN -- 显式地开启一个事务
COMMIT -- 提交事务,使得对数据库做的所有修改成为永久性
ROLLBACK -- 回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。

linux Oracle自定义函数:将使用点分隔符的编码转成层级码格式的编码 SQL语句规范参考
友情链接
  • Mozilla发布Firefox 67.0.4,修复沙箱逃逸漏洞
  • 蚂蚁金服正式成为CNCF云原生计算基金会黄金会员
  • Firefox 68将采用Microsoft BITS安装更新
  • OpenSSH增加对存储在RAM中的私钥的保护
  • 谷歌想实现自己的curl,为什么?
  • Raspberry Pi 4发布:更快的CPU、更大的内存
  • Firefox的UA将移除CPU架构信息
  • Ubuntu放弃支持32位应用程序实属乌龙,Steam会否重回Ubuntu怀抱
  • Qt 5.13稳定版发布:引入glTF 2.0、改进Wayland以及支持Lottie动
  • 红帽企业Linux 7现已内置Redis 5最新版
  • Slack进入微软内部禁用服务清单,GitHub也在其列?
  • 安全的全新编程语言V发布首个可用版本
  • Windows Terminal已上架,快尝鲜
  • 阿里巴巴微服务开源生态报告No.1
  • 面世两年,Google地球将支持所有基于Chromium的浏览器
  • 推进企业容器化持续创新,Rancher ECIC千人盛典完美收官
  • CentOS 8.0最新构建状态公布,或于数周后发布
  • Debian移植RISC
  • 微软拆分操作系统的计划初现雏形
  • Oracle发布基于VS Code的开发者工具,轻松使用Oracle数据库
  • Ubuntu 19.10停止支持32位的x86架构
  • 微软为Windows Terminal推出全新logo
  • 联想ThinkPad P系列笔记本预装Ubuntu系统
  • 微软发布适用于Win7/8的Microsoft Edge预览版
  • 启智平台发布联邦学习开源数据协作项目OpenI纵横
  • 经过六个多月的延迟,微软终于推出Hyper
  • ZFS On Linux 0.8.1 发布,Python可移植性工作
  • DragonFly BSD 5.6.0 发布,HAMMER2状态良好
  • Linux Kernel 5.2
  • CentOS 8.0 看起来还需要几周的时间
  • 百度网盘Linux版正式发布
  • PCIe 6.0宣布:带宽翻倍 狂飙至256GB/s
  • PHP 7.4 Alpha 发布,FFI扩展,预加载Opcache以获得更好的性能
  • Canonical将在未来的Ubuntu版本中放弃对32位架构的支持
  • Scala 2.13 发布,改进的编译器性能
  • 微软的GitHub收购了Pull Panda,并且使所有订阅完全免费
  • Windows Subsystem for Linux 2 (WSL 2)现在适用于Windows 10用
  • Debian 10 “Buster”的RISC
  • MariaDB宣布发布MariaDB Enterprise Server 10.4
  • DXVK 1.2.2 发布,带来微小的CPU开销优化
  • DragonFlyBSD 5.6 RC1 发布,VM优化,默认为HAMMER2
  • PrimeNG 8.0.0 发布,支持Angular 8,FocusTrap等
  • GIMP 2.10.12 发布,一些有用的改进
  • 清华大学Anaconda 镜像服务即将恢复
  • Debian GNU/Linux 10 “Buster” 操作系统将于2019年7月6日发布
  • 时时彩论坛
  • 五星体育斯诺克
  • 北单比分直播
  • 河北11选5走势图
  • 福建体彩36选7开奖结果
  • 九龙图库下载