千家信息网

重新学习Mysql数据库8:MySQL的事务隔离级别实战

发表于:2024-09-21 作者:千家信息网编辑
千家信息网最后更新 2024年09月21日,本文转自: https://blog.csdn.net/sinat_27143551/article/details/80876127本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更
千家信息网最后更新 2024年09月21日重新学习Mysql数据库8:MySQL的事务隔离级别实战

本文转自: https://blog.csdn.net/sinat_27143551/article/details/80876127

本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看

https://github.com/h3pl/Java-Tutorial

喜欢的话麻烦点下Star哈

文章首发于我的个人博客:

www.how2playlife.com

本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。

该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。

如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。

事务的基本要素(ACID)

  1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。

   2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。

   3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。

   4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

事务的并发问题

  1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

  2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。

  3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

  小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

MySQL事务隔离级别

事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted) 是 是 是
读已提交(read-committed) 否 是 是
可重复读(repeatable-read) 否 否 是
串行化(serializable) 否 否 否
默认事务隔离级别:

1、 读未提交例子

(1)打开客户端A,设置事务模式为read uncommitted,查询表

(1) 在A提交事务之前,打开客户端B,更新表

(3)此时,B的事务没提交,但是A已经可以查到B更新的数据

(4)一旦B的事务因某原因回滚,则A查到的数据就是脏数据。

(5)在A执行更新语句,在不知道有其他事务回滚时,会发现结果好奇怪。要解决这个问题可以采用读已提交的事务隔离级别。

2、 读已提交

(1) 在客户端A设置事务模式为read committed;

(2) 在客户端A事务提交之前,打开客户端B,起事务更新表

(3) B的事务还未提交,A不能查到已经更新的数据,解决了脏读问题:

(4) 此时提交客户端B的事务

(5) A执行与上一步相同的查询,结果发现与上一步不同,这就是不可重复读的问题:

3、 可重复读

(1) 打开客户端A,设置事务模式为repeatable read。

(2) 在A事务提交之前,打开客户端B,更新表account并提交:

(3) 在客户端A执行步骤1的查询,zhangsan的balance依然是450与步骤(1)查询结果一致,没有出现不可重复读的问题;接着执行update balance = balance - 50 where id=4;balance没有变成450-50=400;zhangsan的balance值用的是步骤 (2)中的400来算的,所以是350。数据的一致性没有被破坏。

(4)在客户端A提交事务

(5) 在客户端A开启事务,随后在客户端B开启事务,新增一条数据。提交

(6) 在A计算balance之和,值为350+16000+2400=18750,没有把客户端B新增的数据算进去,客户端A提交后再计算balance之和,居然变成了19350,这时因为把客户端B的600算进去了。站在客户的角度,客户是看不到客户端B的,他会觉得天上掉馅饼了,多了600块,这就是幻读,站在开发者的角度,数据的一致性没有破坏。但是在应用程序中,我们的代码可能会把18750提交给用户了,如果一定要避免这种小概率状况的发生,那么就要采取"串行化"的事务隔离级别了。

4、 串行化

(1) 打开客户端A,设置事务隔离级别为serializable并开启事务。

(2) 打开客户端B,同样设置事务隔离级别为serializable,开启事务插入数据,报错。表被锁了,插入失败,mysql中事务隔离级别为serializable时会锁表,因此不会出现幻读的情况,这种隔离级别并发性很低,开发中很少用到。

  补充:

  1、SQL规范所规定的标准,不同的数据库具体的实现可能会有些差异

  2、mysql中默认事务隔离级别是可重复读时并不会锁住读取到的行

  3、事务隔离级别为读提交时,写数据只会锁住相应的行

  4、事务隔离级别为可重复读时,如果有索引(包括主键索引)的时候,以索引列为条件更新数据,会存在间隙锁间隙锁、行锁、下一键锁的问题,从而锁住一些行;如果没有索引,更新数据时会锁住整张表。

  5、事务隔离级别为串行化时,读写数据都会锁住整张表

  6、隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大,鱼和熊掌不可兼得啊。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

事务 数据 客户 客户端 隔离 级别 更新 问题 数据库 一致 技术 索引 一致性 内容 文章 系统 结果 查询 不同 博客 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 集思软件开发有限公司怎么样 关于加强数据库更新的建议 认证服务器怎么样 惠州无限软件开发回收价 戴尔服务器更换电源模块不匹配 镇开展网络安全教育宣传培训总结 迷你世界重力服务器怎么改 绝地求生大逃杀哪个服务器最好 青岛市网络安全管理 数据库id 隔离技术 宁夏 加强网络安全与信息化 数据库 什么叫关系 敏捷软件开发pdf百度云 网络安全防护体系论文 王俊网络安全手抄报 国内企业可以做银行服务器吗 网络技术题库时间咋做 六级无法连接服务器 sql数据库图片储存格式 普洱市网络安全局 众联网络技术有限公司 软件开发商务报价模版 丰台区正规软件开发程序 湖北三力通信网络技术资质 计算机三级网络技术报文分析 数据库中的控制文件相同吗 湖南好的电脑软件开发 软件开发质量控制工具 IT主要设备一定要有服务器吗 厦门起星网络技术有限公司
0