深入理解mysql的隔离级别

建表插入测试数据
A> create table test(id int ,num int) ;
Query OK, 0 rows affected (0.53 sec)

A> insert into test values(1,1);
Query OK, 1 row affected (0.01 sec)

A> insert into test values(2,2);
Query OK, 1 row affected (0.00 sec)

A> insert into test values(3,3);
Query OK, 1 row affected (0.01 sec)

A> select * from test ;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+------+------+
3 rows in set (0.00 sec)

A> show create table test ;
+-------+----------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------------------------------------------+
| test | CREATE TABLE `test` (
`id` int(11) DEFAULT NULL,
`num` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

一。隔离级别read uncommitted,事物A可以读到事物B的未提交数据,未提交数据称为脏数据,因此叫脏读。
A> set session transaction isolation level read uncommitted ;
Query OK, 0 rows affected (0.00 sec)

A> SELECT @@tx_isolation ;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set (0.00 sec)

A> start transaction ;
Query OK, 0 rows affected (0.00 sec)

A> select * from test ;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+------+------+
3 rows in set (0.00 sec)

B> start transaction ;
Query OK, 0 rows affected (0.00 sec)

B> update test set num=10 where id=1 ;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0

B> select * from test ;
+------+------+
| id | num |
+------+------+
| 1 | 10 |
| 2 | 2 |
| 3 | 3 |
+------+------+
3 rows in set (0.00 sec)

A> select * from test ;
+------+------+
| id | num |
+------+------+
| 1 | 10 |
| 2 | 2 |
| 3 | 3 |
+------+------+
3 rows in set (0.01 sec)

B> rollback ;
Query OK, 0 rows affected (0.01 sec)

B> select * from test ;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+------+------+
3 rows in set (0.00 sec)

A> select * from test ;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+------+------+
3 rows in set (0.00 sec)

二。隔离级别read committed ,
对于事物B未提交的DML操作,事物A是看不到的
但是事物A在本身事物操作的过程中(未做commit or rollback),可以读到事物B的已提交数据,这就是不可重复读
下面测试下:
A> set session transaction isolation level read committed ;
Query OK, 0 rows affected (0.00 sec)

A> start transaction ;
Query OK, 0 rows affected (0.00 sec)

A> select * from test ;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+------+------+
3 rows in set (0.00 sec)

B>start transaction ;
Query OK, 0 rows affected (0.00 sec)

B>update test set num=20 where id=1 ;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

B>rollback ;
Query OK, 0 rows affected (0.01 sec)

B>start transaction ;
Query OK, 0 rows affected (0.00 sec)

B>insert into test values(4,4) ;
Query OK, 1 row affected (0.00 sec)

B>select * from test;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
+------+------+
4 rows in set (0.00 sec)

B>rollback ;
Query OK, 0 rows affected (0.01 sec)

B>start transaction ;
Query OK, 0 rows affected (0.00 sec)

B>delete from test where id =1 ;
Query OK, 1 row affected (0.01 sec)

B>select * from test;
+------+------+
| id | num |
+------+------+
| 2 | 2 |
| 3 | 3 |
+------+------+
2 rows in set (0.00 sec)

B>rollback ;
Query OK, 0 rows affected (0.01 sec)

在事物B做这些DML操作的时候,事物A的查询结果一直没变,此时事物A尚未结束
A> select * from test ;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+------+------+
3 rows in set (0.00 sec)

提交事物B的某个操作,事物A里面的对表test的查询结果就变了,因此事物A里面对test表的查询是不可重复的,所以叫不可重复读

三。隔离级别repeatable read
mysql的默认事物隔离级别,防止了脏读和不可重复读,但可能出现幻读
该隔离级别解决了不重复读,保证了同一个事务里,查询的结果都是事务开始时的状态(一致性)。
但是,如果另一个事务同时提交了新数据,本事务再更新时,就会“惊奇的”发现了这些新数据,貌似之前读到的数据是“鬼影”一样的幻觉。

A> set session transaction isolation level repeatable read ;
Query OK, 0 rows affected (0.00 sec)

A> select @@session.tx_isolation ;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| REPEATABLE-READ |
+------------------------+
1 row in set (0.00 sec)

A> start transaction ;
Query OK, 0 rows affected (0.00 sec)

A> select * from test ;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+------+------+
3 rows in set (0.00 sec)

B> start transaction ;
Query OK, 0 rows affected (0.00 sec)

B> update test set num=10 where id=1 ;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

B> select * from test ;
+------+------+
| id | num |
+------+------+
| 1 | 10 |
| 2 | 2 |
| 3 | 3 |
+------+------+
3 rows in set (0.00 sec)

B> commit ;
Query OK, 0 rows affected (0.01 sec)

此处A的修改应该是num=3才对,但是因为幻读,事物B虽然提交了,但事物A读到的还是旧记录,
如同幻影一般,事物A修改后,发现结果是30,而不是想要的结果3
A> update test set num=num*3 where id=1 ;
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0

A> select * from test ;
+------+------+
| id | num |
+------+------+
| 1 | 30 |
| 2 | 2 |
| 3 | 3 |
+------+------+
3 rows in set (0.00 sec)

A> commit ;
Query OK, 0 rows affected (0.01 sec)

四。隔离级别SERIALIZABLE
SERIALIZABLE事务隔离级别最严厉,在进行查询时就会对表或行加上共享锁,其他事务对该表将只能进行读操作,而不能进行写操作。

A> set session transaction isolation level serializable ;
Query OK, 0 rows affected (0.00 sec)

A> select @@session.tx_isolation ;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| SERIALIZABLE |
+------------------------+
1 row in set (0.00 sec)

A> start transaction ;
Query OK, 0 rows affected (0.00 sec)

A> select * from test ;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+------+------+
3 rows in set (0.00 sec)

B> start transaction ;
Query OK, 0 rows affected (0.00 sec)

B> update test set num=3 where id=1 ;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

控制超时的参数
innodb_lock_wait_timeout | 120

时间: 2024-09-30 11:09:33

深入理解mysql的隔离级别的相关文章

深入理解mysql事务隔离级别

mysql支持4种事务隔离级别分别为 Read Uncommitted 读未提交 Read Committed 读已提交 Repeatable Read 可重复读 *注意这个概念容易混,下面细说 Serializable 串行化事务操作 1.Read Uncommitted 读未提交 事务隔离级别设为Read Uncommitted时,能查询到其他事务已修改但尚未提交的数据,若后续其他事务发生回滚,则造成了脏读.是最低的事务隔离级别 2.Read Committed 读已提交 事务隔离级别设为R

查询修改mysql事务隔离级别

1.查看当前会话隔离级别 select @@tx_isolation; 2.查看系统当前隔离级别 select @@global.tx_isolation; 3.设置当前会话隔离级别 set tx_isolation='read-committed'; 4.设置系统当前隔离级别 set global transaction isolation level read committed; 关于隔离级别的理解: 1.read uncommitted 可以看到未提交的数据(脏读),举个例子:别人说的话

查询mysql事务隔离级别

查询mysql事务隔离级别 查询mysql事务隔离级别 分类: DB2011-11-26 13:12 2517人阅读 评论(0) 收藏 举报 mysqlsessionjava 1.查看当前会话隔离级别 select @@tx_isolation; 2.查看系统当前隔离级别 select @@global.tx_isolation; 3.设置当前会话隔离级别 set session transaction isolatin level repeatable read; 4.设置系统当前隔离级别 s

Mysql事务-隔离级别

MYSQL事务-隔离级别 事务是什么? 事务简言之就是一组SQL执行要么全部成功,要么全部失败.MYSQL的事务在存储引擎层实现. 事务都有ACID特性: 原子性(Atomicity):一个事务必须被视为一个不可分割的单元: 一致性(Consistency):数据库总是从一种状态切换到另一种状态: 隔离性(Isolation):通常来说,事务在提交前对于其他事务不可见: 持久性(Durablity):一旦事务提交,所做修改永久保存数据库: 事务最常用的例子就是银行转账.假设polo需给lynn转

MySQL事务隔离级别为"REPEATABLE-READ"下的"幻读"现象

MySQL事务隔离级别为"REPEATABLE-READ"下的"幻读"现象 关于mysql命令行中事务控制的语句见该文章:http://my.oschina.net/xinxingegeya/blog/296459 本片参考文章:http://blog.csdn.net/jiao_fuyou/article/details/16368827 http://www.cnblogs.com/hancf/archive/2012/08/28/2660422.html my

Mysql得隔离级别

一.首先什么是事务? 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做. 事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交.如果其中一个步骤失败,将发生回滚操作,撤消撤消之前到事务开始时的所以操作. 二.事务的 ACID 事务具有四个特征:原子性( Atomicity ).一致性( Consistency ).隔离性( Isolation )和持续性( Dura

Mysql的隔离级别

一.首先什么是事务? 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做. 事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交.如果其中一个步骤失败,将发生回滚操作,撤消撤消之前到事务开始时的所以操作. 二.事务的 ACID 事务具有四个特征:原子性( Atomicity ).一致性( Consistency ).隔离性( Isolation )和持续性( Dura

【不错】MySQL 事务隔离级别

一.事务描述 1.事务的四个特性 ACID 1. A:原子性 = 一个事务或者都成功.或者都失败: 2. C:一致性 = 在整个事务的生命周期里面,查询到的数据是一致的: MVCC多版本并发控制:利用undo保存某一时刻数据快照,通过版本号来减少锁的争用,保证各个事务互不影响. 3. I:  隔离性 = 隔离级别: 4. D:持久性 = 只要事务commit,这个事务不会因为系统的崩溃而丢失: 持久性和原子性对于所有的支持事务的数据库都是一样的,都满足. 2.常见事务格式 start trans

理解MySql事务隔离机制、锁以及各种锁协议

一直以来对数据库的事务隔离机制的理解总是停留在表面,其内容也是看一遍忘一边.这两天决定从原理上理解它,整理成自己的知识.查阅资料的过程中发现好多零碎的概念如果串起来足够写一本书,所以在这里给自己梳理一个脉络,具体的内容参考引文或在网上搜一下.由于平时接触最多的是MySQL,所以文章中某些部分是MySQL特有的特性,请读者注意. 数据库并发操作会引发的问题: 多个事务同时访问数据库时候,会发生下列5类问题,包括3类数据读问题(脏读,不可重复读,幻读),2类数据更新问题(第一类丢失更新,第二类丢失更