在讲mysql事物隔离级别之前,我们先简单说说mysql的锁和事务。
一:数据库锁
因为数据库要解决并发控制问题。在同一时刻,可能会有多个客户端对同一张表进行操作,比如有的在读取该行数据,其他的尝试去删除它。为了保证数据的一致性,数据库就要对这种并发操作进行控制,因此就有了锁的概念。
锁的分类
从对数据库操作的类型分
读锁(共享锁):针对同一块数据,多个读操作可以同时进行而不会互相影响。由读表操作加上的锁,加锁后其他用户只能获取该表或行的共享锁,不能获取排它锁,也就是说只能读不能写。
写锁(排它锁):当当前写操作没有完成之前,它会阻断其他写锁和读锁。由写表操作加上的锁,加锁后其他用户不能获取该表或行的任何锁。
从锁定的数据范围分
表锁:锁定某个表。
行锁 :锁定某行。
为了尽可能 提高数据库的并发度,每次锁定的数据范围越小越好。理论上每次只锁定当前操作的数据的方案会得到最大的并发度,但是管理锁是很耗费资源的事情。因此数据库系统需要在高并发响应和系统性能两方面进行平衡,这样就产生了“锁粒度”的概念。
锁粒度
表锁:管理锁的开销最小,同时允许的并发量也最小的锁机制。MyIsam存储引擎使用的锁机制。当要写入数据时,把整个表都锁上,此时其他读、写动作一律等待。在MySql中,除了MyIsam存储引擎使用这种锁策略外,MySql本身也使用表锁来执行某些特定动作,比如alter table.
行锁:可以支持最大并发的锁策略。InnoDB和Falcon两张存储引擎都采用这种策略。
MySql是一种开放的架构,你可以实现自己的存储引擎,并实现自己的锁粒度策略,不像Oracle,你没有机会改变锁策略,Oracle采用的是行锁。从大到小,mysql服务器仅支持表级锁,行锁需要存储引擎完成。粒度越精细,并发性越好。即行锁的并发性最好,但需要存储引擎的支持。
二:事务
从业务角度出发 ,对数据库的一组操作要求保持4个特征:
Atomicity:原子性。
Consistency:一致性。
Isolation:隔离性。
Durability:持久性。
为了更好地理解ACID,以银行账户转账为例: 
1 START TRANSACTION;
2 SELECT balance FROM checking WHERE customer_id = 10233276;
3 UPDATE checking SET balance = balance - 200.00 WHERE customer_id = 10233276;
4 UPDATE savings SET balance = balance + 200.00 WHERE customer_id = 10233276;
5 COMMIT;
原子性:要么完全提交(10233276的checking余额减少200,savings 的余额增加200),要么完全回滚(两个表的余额都不发生变化)。
一致性:这个例子的一致性体现在 200元不会因为数据库系统运行到第3行之后,第4行之前时崩溃而不翼而飞,因为事物还没有提交。 
隔离性:允许在一个事务中的操作语句会与其他事务的语句隔离开,比如事务A运行到第3行之后,第4行之前,此时事务B去查询checking余额时,它仍然能够看到在事务A中被减去的200元,因为事务A和B是彼此隔离的。在事务A提交之前,事务B观察不到数据的改变。
持久性:这个很好理解。
事务跟锁一样都会需要大量工作,因此你可以根据你自己的需要来决定是否需要事务支持,从而选择不同的存储引擎。 
三:事务隔离级别
SQL标准定义了4中隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。
Read Uncommitted(读取未提交内容) 
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。  
Read Committed(读取提交内容)
这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。 
Repeatable Read(可重读)
这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。 不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时, 另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。 InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。 
Serializable(可串行化)  
这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
 这四种隔离级别采取不同的锁类型来实现,若读取的是同一个数据的话,就容易发生问题。例如:
脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。
幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。
不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。
案例:
Read Uncommitted(读取未提交内容) 
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
1.分别在A、B两个客户端执行: 

 
2. 
3. A: 
4. root@(none) 10:54>SET GLOBAL tx_isolation='READ-UNCOMMITTED';
5. Query OK, 0 rows affected (0.00 sec)
6. 
7. root@(none) 10:54>SELECT @@tx_isolation;
8. +------------------+
9. | @@tx_isolation |
10. +------------------+
11. | READ-UNCOMMITTED |
12. +------------------+
13. 1 row in set (0.00 sec)
14. 
15. root@(none) 10:54>use test;
16. Database changed
17. root@test 10:55>begin;
18. Query OK, 0 rows affected (0.00 sec)
19. 
20. root@test 10:55>select * from test1;
21. +------+
22. | a |
23. +------+
24. | 1 |
25. | 2 |
26. | 3 |
27. | 4 |
28. +------+
29. 4 rows in set (0.00 sec)
30. 
31. B上: 
32. root@test 10:58>select @@tx_isolation;
33. +------------------+
34. | @@tx_isolation |
35. +------------------+
36. | READ-UNCOMMITTED |
37. +------------------+
38. 1 row in set (0.00 sec)
39. 
40. root@test 10:58>
41. root@test 10:58>begin;
42. Query OK, 0 rows affected (0.00 sec)
43. 
44. root@test 10:58>insert into test.test1 values (999);
45. Query OK, 1 row affected (0.00 sec)
46. 
47. root@test 10:58>select * from test.test1;
48. +------+
49. | a |
50. +------+
51. | 1 |
52. | 2 |
53. | 3 |
54. | 4 |
55. | 999 |
56. +------+
57. 5 rows in set (0.00 sec)
58. 此处B客户端并未commit;
59. 
60. 再查看A客户端: 
61. root@test 10:58>select * from test1;
62. +------+
63. | a |
64. +------+
65. | 1 |
66. | 2 |
67. | 3 |
68. | 4 |
69. | 999 |
70. +------+
71. 5 rows in set (0.00 sec)
72. 
 

73. 此处A可以看到新的记录了。  
Read Committed(读取提交内容)
这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。 这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。 
1.在A客户端:

 
2. root@(none) 11:10>SET GLOBAL tx_isolation='READ-COMMITTED';
3. Query OK, 0 rows affected (0.00 sec)
4. 
5. root@(none) 11:10>SELECT @@tx_isolation;
6. +----------------+
7. | @@tx_isolation |
8. +----------------+
9. | READ-COMMITTED |
10. +----------------+
11. 1 row in set (0.00 sec)
12. 
13. root@(none) 11:10>
14. root@(none) 11:10>begin;
15. Query OK, 0 rows affected (0.00 sec)
16. 
17. root@(none) 11:10>select * from test.test1;
18. +------+
19. | a |
20. +------+
21. | 1 |
22. | 2 |
23. | 3 |
24. | 4 |
25. +------+
26. 
27. 在B客户端执行:
28. root@test 11:11>begin;
29. Query OK, 0 rows affected (0.00 sec)
30. 
31. root@test 11:11>select * from test.test1;
32. +------+
33. | a |
34. +------+
35. | 1 |
36. | 2 |
37. | 3 |
38. | 4 |
39. +------+
40. 4 rows in set (0.00 sec)
41. 
42. root@test 11:11>
43. root@test 11:11>delete from test.test1 where a=1;
44. Query OK, 1 row affected (0.00 sec)
45. 
46. root@test 11:12>select * from test.test1;
47. +------+
48. | a |
49. +------+
50. | 2 |
51. | 3 |
52. | 4 |
53. +------+
54. 
55. 此时查询A客户端:
56. 
57. root@(none) 11:12>select * from test.test1;
58. +------+
59. | a |
60. +------+
61. | 1 |
62. | 2 |
63. | 3 |
64. | 4 |
65. +------+
66. 此处看出A客户端无变化,在B客户端执行commit后再查看A客户端:
67. 
68. root@(none) 11:13>select * from test.test1;
69. +------+
70. | a |
71. +------+
72. | 2 |
73. | 3 |
74. | 4 |
75. +------+
76. 
77. 可以看到A客户端的数据已经变了。已提交读只允许读取已提交的记录,但不要求可重复读。
78. 用MVCC来说就是读取当前行的最新版本。 
 

 Repeatable Read(可重读)
这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。 不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。 简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。 InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。 
1.在A客户端上:

 
2. root@(none) 11:17>SET GLOBAL tx_isolation='REPEATABLE-READ';
3. Query OK, 0 rows affected (0.00 sec)
4. 
5. root@(none) 11:17>
6. root@(none) 11:17>
7. root@(none) 11:17>SELECT @@tx_isolation;
8. +-----------------+
9. | @@tx_isolation |
10. +-----------------+
11. | REPEATABLE-READ |
12. +-----------------+
13. 1 row in set (0.00 sec)
14. 
15. root@(none) 11:17>BEGIN;
16. Query OK, 0 rows affected (0.00 sec)
17. 
18. 在B客户端上:
19. root@test 11:20>select @@tx_isolation;
20. +-----------------+
21. | @@tx_isolation |
22. +-----------------+
23. | REPEATABLE-READ |
24. +-----------------+
25. 1 row in set (0.00 sec)
26. 
27. root@test 11:20>insert into test.test1 values (555);
28. Query OK, 1 row affected (0.00 sec)
29. 
30. root@test 11:20>commit;
31. Query OK, 0 rows affected (0.00 sec)
32. 
33. root@test 11:21>
34. root@test 11:21>select * from test.test1;
35. +------+
36. | a |
37. +------+
38. | 2 |
39. | 3 |
40. | 4 |
41. | 555 |
42. +------+
43. 4 rows in set (0.00 sec)
44. 此处在B客户端上已经commit.
45. 
46. 然后查看A客户端:
47. 
48. root@(none) 11:22>SELECT * FROM test.test1;
49. +------+
50. | a |
51. +------+
52. | 2 |
53. | 3 |
54. | 4 |
55. +------+
56. 3 rows in set (0.00 sec)
57. 
58. root@(none) 11:22>commit;
59. Query OK, 0 rows affected (0.00 sec)
60. 
61. 
62. root@(none) 11:22>SELECT * FROM test.test1;
63. +------+
64. | a |
65. +------+
66. | 2 |
67. | 3 |
68. | 4 |
69. | 555 |
70. +------+
71. 4 rows in set (0.00 sec)
72. 
73. 在A客户端上提交后可以看到新数据。
74. 也就是说在可重复读隔离级别只能读取已经提交的数据,并且在一个事务内,读取的数据就是事务开始时的数据。 
 

 Serializable(可串行化)
这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。 
该类型在A客户端操作test.test1表时会锁定该数据,如果B客户端想要操作test.test1就需要等待A客户端释放。 
https://blog.csdn.net/weixin_40255793/article/details/79735665

MySql锁和事务隔离级别的更多相关文章

  1. 面试必问的MySQL锁与事务隔离级别

    之前多篇文章从mysql的底层结构分析.sql语句的分析器以及sql从优化底层分析, 还有工作中常用的sql优化小知识点.面试各大互联网公司必问的mysql锁和事务隔离级别,这篇文章给你打神助攻,一飞 ...

  2. MySQL锁与事务隔离级别

    一.概述 1.锁的定义 锁是计算机协调多个进程或线程并发访问某一资源的机制. 在数据库中,除了传统的计算资源(如CPU.RAM.IO等)的争用以外,数据也是一种供需要用户共享的资源.如何保证数据并发访 ...

  3. 【MySQL】深入理解MySQL锁和事务隔离级别

    先看个小案例: 话不多说,上案例,先创建一个表 mysql> CREATE TABLE IF NOT EXISTS `account`( `id` INT UNSIGNED AUTO_INCRE ...

  4. 深入理解mysql锁与事务隔离级别

    一.锁 1.锁的定义     锁即是一种用来协调多线程或进程并发使用同一共享资源的机制 2.锁的分类 从性能上分类:乐观锁和悲观锁 从数据库操作类型上分类:读锁和写锁 从操作粒度上分类:表锁和行锁 2 ...

  5. 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?

    在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...

  6. 第36讲 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景

    在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...

  7. mysql中不同事务隔离级别下数据的显示效果--转载

    事务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查询语句因为崩溃或其他原因而无法执行,那么所有的语句就都 ...

  8. 浅谈mysql中不同事务隔离级别下数据的显示效果

    事务的概念 事 务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查 询语句因为崩溃或其他原因而无法执行,那 ...

  9. 事务,Oracle,MySQL及Spring事务隔离级别

    一.什么是事务: 事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败. 二.事务特性(4种): 原子性 (atomicity):强调事务的不可分割:一致性 (consiste ...

随机推荐

  1. Winform 多项目共用AssemblyInfo解决方案

    Winform 多项目共用AssemblyInfo解决方案: 操作步骤如下: 第一步:复制任何项目中的AssemblyInfo.cs文件至指定目录 第二步:删除所有项目的AssemblyInfo.cs ...

  2. 使用python下载图片(福利)

    刚学python 没多久, 代码处处是漏洞,也希望各位大佬理解一下 爬出来的图片... 使用的 是 https://www.tianapi.com/  接口下的 美女图片... (需要自己注册一个账号 ...

  3. sql 语句用法

    一.基础 1.说明:创建数据库CREATE DATABASE database-name 2.说明:删除数据库drop database dbname 3.说明:备份sql server--- 创建 ...

  4. [SDOI2008]山贼集团

    题目描述 某山贼集团在绿荫村拥有强大的势力,整个绿荫村由\(N\)个连通的小村落组成,并且保证对于每两个小村落有且仅有一条简单路径相连. 小村落用阿拉伯数字编号为\(1,2,3,4, \dots ,n ...

  5. 2019 ICPC 南昌网络赛I:Yukino With Subinterval(CDQ分治)

    Yukino With Subinterval Yukino has an array a_1, a_2 \cdots a_na1,a2⋯*a**n*. As a tsundere girl, Yuk ...

  6. Gym - 102141D 通项公式 最短路

    题目很长,但是意思就是给你n,A,B,C,D n表示有n个城市 A是飞机的重量 B是一个常数表示转机代价 C是单位燃油的价格 D是一个常数 假设一个点到另外一个点的距离为整数L 起飞前的油量为f  则 ...

  7. 十一届河南省赛-checkpoints(个人解法)-能AC代码

    大致题意: zznuoj,大致题意:从A点出发达到B点去解救人质,再从B点返回到A点,经历第二遍的点只计算一次即可,AB两点不计数!求完成任务最少需要经过的点数. 大致思路:暴力!从起点到终点,和从终 ...

  8. TCP/IP协议簇 端口 三次握手 四次挥手 11种状态集

    第一章:概念介绍 1.1 VLAN 1.1.1 什么是VLAN VLAN (Virturl LAN) ,翻译成中文是:“虚拟局域网”.VLAN可以是由少数几台家用计算机构成的网络,也可以是数以百计的计 ...

  9. ProjectEuler237 Tours on a 4 x n playing board

    思路是这样的 插头dp-->打表-->OEIS查表-->通项公式-->矩阵快速幂优化线性递推 OEIS竟然有这个东西的生成函数啊 答案为15836928 这是最终代码 #inc ...

  10. kafka什么时候会丢消息(转)

    因为在具体开发中某些环节考虑使用kafka却担心有消息丢失的风险,本周结合项目对kafka的消息可靠性做了一下调研和总结: 首先明确一下丢消息的定义.kafka集群中的部分或全部broker挂了,导致 ...