当前位置: 首页 > 编程日记 > 正文

关于MySQL的四种事务隔离级别!

本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB

一、事务的基本要素(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)

mysql默认的事务隔离级别为repeatable-read。在这里插入图片描述

四、用例子说明各个隔离级别的情况

1、读未提交
    (1)打开一个客户端A,并设置当前事务模式为read uncommitted(未提交读),查询表account的初始值。
在这里插入图片描述
    (2)在客户端A的事务提交之前,打开另一个客户端B,更新表account。
在这里插入图片描述
   (3)这时,虽然客户端B的事务还没提交,但是客户端A就可以查询到B已经更新的数据。
   在这里插入图片描述
   (4)一旦客户端B的事务因为某种原因回滚,所有的操作都将会被撤销,那客户端A查询到的数据其实就是脏数据。
 在这里插入图片描述
   (5)在客户端A执行更新语句update account set balance = balance - 50 where id =1,lilei的balance没有变成350,居然是400,是不是很奇怪,数据不一致啊,如果你这么想就太天真 了,在应用程序中,我们会用400-50=350,并不知道其他会话回滚了,要想解决这个问题可以采用读已提交的隔离级别。

在这里插入图片描述
2、不可重复读
    (1)打开一个客户端A,并设置当前事务模式为read committed(未提交读),查询表account的所有记录。
    在这里插入图片描述
    (2)在客户端A的事务提交之前,打开另一个客户端B,更新表account。
    在这里插入图片描述
    (3)这时,客户端B的事务还没提交,客户端A不能查询到B已经更新的数据,解决了脏读问题。
    在这里插入图片描述
    (4)客户端B的事务提交。
    在这里插入图片描述
    
    (5)客户端A执行与上一步相同的查询,结果 与上一步不一致,即产生了不可重复读的问题。
    
在这里插入图片描述

3、可重复读
    (1)打开一个客户端A,并设置当前事务模式为repeatable read,查询表account的所有记录。
    在这里插入图片描述
    (2)在客户端A的事务提交之前,打开另一个客户端B,更新表account并提交。
    在这里插入图片描述
    
    (3)在客户端A查询表account的所有记录,与步骤(1)查询结果一致,没有出现不可重复读的问题。
    在这里插入图片描述
    (4)在客户端A,接着执行update balance = balance - 50 where id = 1,balance没有变成400-50=350,lilei的balance值用的是步骤(2)中的350来算的,所以是300,数据的一致性倒是没有被破坏。可重复读的隔离级别下使用了MVCC机制,select操作不会更新版本号,是快照读(历史版本);insert、update和delete会更新版本号,是当前读(当前版本)。
    在这里插入图片描述
    
    (5)重新打开客户端B,插入一条新数据后提交。
    在这里插入图片描述
    (6)在客户端A查询表account的所有记录,没有 查出 新增数据,所以没有出现幻读。
    在这里插入图片描述
4.串行化
    (1)打开一个客户端A,并设置当前事务模式为serializable,查询表account的初始值。

mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)mysql> select * from account;
+------+--------+---------+
| id   | name   | balance |
+------+--------+---------+
|    1 | lilei  |   10000 |
|    2 | hanmei |   10000 |
|    3 | lucy   |   10000 |
|    4 | lily   |   10000 |
+------+--------+---------+
4 rows in set (0.00 sec)

(2)打开一个客户端B,并设置当前事务模式为serializable,插入一条记录报错,表被锁了插入失败,mysql中事务隔离级别为serializable时会锁表,因此不会出现幻读的情况,这种隔离级别并发性极低,开发中很少会用到。

mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)mysql> insert into account values(5,'tom',0);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

补充:

1. 事务隔离级别为读提交时,写数据只会锁住相应的行。
2. 事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key锁;如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以防止幻读。
3. 事务隔离级别为串行化时,读写数据都会锁住整张表。
4. 隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。

相关文章:

[PKUWC2018]随机算法

题意&#xff1a;https://loj.ac/problem/2540 给定一个图(n<20)&#xff0c;定义一个求最大独立集的随机化算法 产生一个排列&#xff0c;依次加入&#xff0c;能加入就加入 求得到最大独立集的概率 loj2540 「PKUWC 2018」随机算法 本质就是计数题 每个点有三种状态&#…

angular4 note

纪录作为新手&#xff0c;用新版angular遇到的一些细节点 1. .angular-cli.json文件 一开始没注意这个文件干啥的&#xff0c;直到我发现有个第三方js&#xff0c;我既没有在index.html里看到引用&#xff0c;也没看到在js代码里有import&#xff0c;找了好久&#xff0c;在这…

初学 Delphi 嵌入汇编[3] - 第一个 Delphi 与汇编的例子

前面知道了一个汇编的赋值指令(MOV), 再了解一个加法指令(ADD), 就可以做个例子了.譬如: ADD AX,BX; 这相当于 Delphi 中的 AX : AX BX;另外提前来个列表 - Delphi 可以用汇编管理以下寄存器:32 位寄存器: EAX EBX ECX EDX ESP EBP ESI EDI16 位寄存器: AX BX CX DX SP BP SI …

通过应用程序域AppDomain加载和卸载程序集之后,如何再返回原来的主程序域

实现目的&#xff1a;动态加载dll&#xff0c;执行完毕之后可以随时卸载掉&#xff0c;并可以替换这些dll&#xff0c;以在运行中更新dll中的类。 其实就是通过应用程序域AppDomain加载和卸载程序集。 在这方面微软有篇文章http://www.microsoft.com/china/msdn/archives/libra…

Sql语法---DDL

1.SQL的定义 结构化查询语言(Structured Query Language)简称SQL,SQL语句就是对数据库进行操作的一种语言。 2.SQL的作用 通过SQL语句我们可以方便的操作数据库中的数据、表、数据库等。 3.SQL的分类 1. DDL(Data Definition Language)数据定义语言用来定义数据库对象&#xff…

Java程序员三年的工作经验,却不如一个新人的工资高???

文章目录一、关于程序员的几个阶段第一阶段&#xff1a;三年第二阶段&#xff1a;五年第三阶段&#xff1a;十年二、关于项目经验三、关于专业技能1、基本语法2、集合3、设计模式4、多线程5、JDK源码6、框架7、数据库8、数据结构和算法分析9、Java虚拟机10、Web方面的一些问题四…

视觉稿与H5页面之间的终端适配

移动端页面开发备注&#xff1a;该篇文章使用宽为750px&#xff08;iPhone6的设备像素&#xff09;的视觉稿编写html代码&#xff1a;<!DOCTYPE html><html><head> <title></title> <meta charset"utf-8" /></head><bo…

欢迎大家批评:CSDN Blog用户体验调查

CSDN Blog自2004年7月上线以来&#xff0c;得到了各位用户的大力支持&#xff0c;已经成为大家发表专业技术文章和进行技术交流的园地。为了给各位作者和读者提供更好的服务&#xff0c;我们组织了这次用户问卷调查&#xff0c;希望大家能够将意见反馈给我们。 CSDN Blog团…

几个我收藏的经典网站

壁纸酷:[url]http://www.bizhiku.net[/url],XP壁纸,vista壁纸,汽车壁纸,风景壁纸,游戏壁纸,美女桌面壁纸,3d壁纸,日历月历壁纸等等,精美桌面壁纸下载.WAP中国:[url]http://www.wapcn.net[/url],专业的手机资源网站下载,手机铃声,手机游戏,手机壁纸,手机电影,手机软件,手机主题下…

用Java求一个三位数,该三位数是与其每位数字的阶乘之和

题目&#xff1a;一个三位数&#xff0c;该三位数与其每位数字的阶乘之和 代码&#xff1a; public class TestSum {public static void main(String[] args) {int a, b, c, i;//for循环找那个满足条件的三位数&#xff08;i&#xff09;for (i 100 ; i < 999; i) {a i %…

Storm 0.9安装指南

Storm 0.9.2安装指南0 Storm0.9的亮点引用网上的描写叙述&#xff1a;“Storm 0.9.0.1版本号的第一亮点是引入了netty transport。Storm网络传输机制实现可插拔形式&#xff0c;当前包括两种方式&#xff1a;原来的0mq传输&#xff0c;以及新的netty实现。在早期版本号中&#…

WinForm 设置初始位置在屏幕右下角

base.Location new Point(Screen.PrimaryScreen.WorkingArea.Width - base.Width, Screen.PrimaryScreen.WorkingArea.Height - base.Height);转载于:https://www.cnblogs.com/RobotTech/archive/2008/01/31/1059548.html

给博客增加了一个主题Nautica02Liquid

在Open Source Web Design上看到一个主题&#xff0c;觉得很不错&#xff0c;于是将其Adapted成BlogEngine的主题&#xff0c;费劲功夫改出来后发现效果不是很好&#xff0c;个人认为是汉字在某些精美的主题上倒是不很适应&#xff0c;没有办法…… 但是总归是做出来了&#xf…

php 基于socket的基本通信

php 基于socket的基本通信 1、前言 Socket是应用层与TCP/IP协议族通信的中间软件抽象层&#xff0c;它是一组接口。在设计模式中&#xff0c;Socket其实就是一个门面模式&#xff0c;它把复杂的TCP/IP协议族隐藏在Socket接口后面&#xff0c;对用户来说&#xff0c;一组简单的接…

SpringBoot实战(十四)之整合KafKa

本人今天上午参考了不少博文&#xff0c;发现不少博文不是特别好&#xff0c;不是因为依赖冲突问题就是因为版本问题。 于是我结合相关的博文和案例&#xff0c;自己改写了下并参考了下&#xff0c;于是就有了这篇文章。希望能够给大家帮助&#xff0c;少走一些弯路。 一、KafK…

Java 对象的生命周期

Java对象的生命周期 在Java中&#xff0c;对象的生命周期包括以下几个阶段&#xff1a; 创建阶段(Created)应用阶段(In Use)不可见阶段(Invisible)不可达阶段(Unreachable)收集阶段(Collected)终结阶段(Finalized)对象空间重分配阶段(De-allocated) 图1. JavaObject Life Cyc…

ThinkPad -- Intel 无线网卡网络连接方法限制及无法用 Fn + F5 控制的问题

[url]http://www-900.ibm.com/cn/support/tscdoc/html/JLII-6R6E5C.HTML[/url]文章编号:JLII-6R6E5CThinkPad -- Intel 无线网卡网络连接方法限制及无法用 Fn F5 控制的问题适用机型:所有ThinkPad R50; 所有ThinkPad R50e; 所有ThinkPad R50p; 所有ThinkPad R51; 所有ThinkPad…

TreeSet集合(自然排序和比较器排序)

TreeSet集合自然排序和比较器排序 ​ 当指执行插入排序、希尔排序、归并排序等算法时&#xff0c;比较两个对象“大小”的比较操作。我们很容易理解整型的 i>j 这样的比较方式&#xff0c;但当我们对多个对象进行排序时&#xff0c;如何比较两个对象的“大小”呢&#xff1…

java字节流

一 字节流 1.1字节输出流OutputStream OutputStream是一个抽象类&#xff0c;操作的数据都是字节。 输出流中定义都是写write方法&#xff0c;如下图: 1.1.1 FileOutputStream类 OutputStream有很多子类&#xff0c;其中子类FileOutputStream可用来写入数据到文件。FileOutput…

MySQL:讨人喜欢的 MySQL replace into 用法(insert into 的增强版)

讨人喜欢的 MySQL replace into 用法&#xff08;insert into 的增强版&#xff09; 在向表中插入数据的时候&#xff0c;经常遇到这样的情况&#xff1a;1. 首先判断数据是否存在&#xff1b; 2. 如果不存在&#xff0c;则插入&#xff1b;3.如果存在&#xff0c;则更新。 在 …

读农民工兄弟学C#文章后的感觉

呵呵,这些文章让原本枯燥的技术文章变得简单,通俗,易懂此类文章是编程入门新手必读的好文章,当然高手可以看一下这些文章的语言风格,等日后自己出书时,可以参考之!哈哈,哪天我也出一本属于自己的技术书^_^好可惜的是自己离"高手"还有那么一段路要走!当然喽,我不是高手…

36晋级12第五场:冯志刚决胜入围(节目视频)

视频地址&#xff1a;[url]http://win.cn.yahoo.com/070613/16/mn53.html[/url]比赛时间&#xff1a;2007年4月17日 选手&#xff1a;王阳、冯志刚、刘恩霞、王嵩 评委&#xff1a; 熊晓鸽&#xff1a;IDG创业投资基金 创始合伙人 马云&#xff1a;阿里巴巴集团董事局主席及雅虎…

顯示密碼安全性強度

<div class"from-nav"><div class"Mtitle"><span>密码:</span></div><div class"Mright"><input name"password"type"password"id"password"size"20"class&quo…

HashMap集合遍历的五种方式

文章目录创建HashMap集合&#xff0c;添加数据一、第一种foreach遍历二、第二种foreach遍历三、第一种迭代器遍历 效率高&#xff08;建议使用&#xff09;四、第二种迭代器遍历 效率低&#xff08;不建议使用&#xff09;五、JDK8新特性&#xff0c;通过lambda遍历Map创建Hash…

JAVA核心技术I---JAVA基础知识(查漏补缺private,static)

一&#xff1a;private对于类和对象&#xff08;同C&#xff09; private是只有这个类内部可以访问&#xff08;类的成员函数和定义初始化&#xff09; private是类之间的限制&#xff0c;而不是对对象的限制《重点》 同类对象是可以直接访问对象的私有成员 class priTest{priv…

『TensorFlow』命令行参数解析

argparse很强大&#xff0c;但是我们未必需要使用这么繁杂的东西&#xff0c;TensorFlow自己封装了一个简化版本的解析方式&#xff0c;实际上是对argparse的封装 脚本化调用tensorflow的标准范式&#xff1a; import pprint import tensorflow as tfflags tf.app.flags# 脚本…

IIS重起批处理

将以下代码保存到一个BAT文件中,执行后便可释放所有被锁定的组件。执行顺序是&#xff1a;停止&#xff37;&#xff37;&#xff37;服务&#xff0d;〉停止组件保护&#xff0d;〉开启组件保护&#xff0d;〉开启&#xff37;&#xff37;&#xff37;服务。net stop w3svc /…

RenderTree渲染树

RenderTree渲染树对类中的静态成员有很重要的关系&#xff0c;这个和多态是有很重要的关系&#xff0c;举个简单的例子&#xff0c;在游戏中&#xff0c;马里奥需要渲染&#xff0c;蘑菇也需要渲染&#xff0c;怪兽也需要渲染&#xff0c;其是串在一个树上的&#xff0c;但是不…

JAVA IO流复制文件夹及里面的所有文件

public static void main(String[] args) throws Exception {//复制到哪个路径&#xff08;path&#xff09;中String path "E:\\main";File file new File("F:\\main");copyAll(file, path);}public static void copy(File file, String path) throws E…

python RSA 加密与签名

PyCrypto装起来就简单多了&#xff0c;我是直接 sudo easy_install pycrypto 直接搞定的先生成rsa的公私钥&#xff1a;打开控制台&#xff0c;输入 openssl 再输入 genrsa -out private.pem 1024 来生成私钥接着输入 rsa -in private.pem -pubout -out public.pem 来生成公钥$…