参考了这篇文章的一些内容:

http://xm-king.iteye.com/blog/770721

记住以下这张表:

我在springdemo库里面建了一个表:

CREATE TABLE `tx` (
`id` bigint(11) NOT NULL auto_increment,
`num` bigint(11) default 0 COMMENT '用户名',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='事务隔离级别测试表';

Mysql通过以下语句可以查询

SELECT @@tx_isolation;
SELECT @@global.tx_isolation; 
SELECT @@session.tx_isolation; 

默认的是 REPEATABLE-READ

可以通过以下方式修改隔离级别:

set tx_isolation='read-committed';

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

mysql> set tx_isolation='read-committed';
Query OK, 0 rows affected (0.00 sec)

mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1 row in set (0.00 sec)

但是,注意以上的改动,只能针对当前会话。

另起一个客户端,输入

select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+

————————————————————————————————

以下是各种情况的测试:

READ-UNCOMMITTED

update tx set num=11 where id=1;
ERROR 1665 (HY000): Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.

READ-COMMITTED

update tx set num=11 where id=1;
ERROR 1665 (HY000): Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.

REPEATABLE-READ

A:

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec) mysql> select * from tx; (B更新前)
+----+------+
| id | num |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+------+
3 rows in set (0.00 sec) mysql> select * from tx; (B更新后)
+----+------+
| id | num |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+------+
3 rows in set (0.00 sec) mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from tx;
+----+------+
| id | num |
+----+------+
| 1 | 10 |
| 2 | 2 |
| 3 | 3 |
+----+------+

可以看出,A的事务中,看不到B对数据的更新。

同样是 REPEATABLE-READ

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec) mysql> select * from tx;
+----+------+
| id | num |
+----+------+
| 1 | 10 |
| 2 | 2 |
| 3 | 3 |
+----+------+
3 rows in set (0.00 sec) mysql> select * from tx;
+----+------+
| id | num |
+----+------+
| 1 | 10 |
| 2 | 2 |
| 3 | 3 |
+----+------+
3 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

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

另一个客户端,insert 了一条记录.

对于正常的repeatable-read级别,是有可能出现幻读的情况,也就是说,第二遍的时候,A能够读到新插入的数据。

但是,InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。

所以我上面用InnoDB引擎创建的数据库,就没有出现幻读的情况。

SERIALIZABLE

这里注意,只需要对使用事务Transaction的客户端设置SERIALIZABLE ,其他客户端的级别是什么都行,比如REPEATABLE-READ .

A

mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE |
+----------------+
1 row in set (0.00 sec) mysql> start transaction;
Query OK, 0 rows affected (0.00 sec) mysql> select * from tx;
+----+------+
| id | num |
+----+------+
| 1 | 10 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
5 rows in set (0.00 sec) mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

B

mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec) mysql> insert into tx values(5,5);
Query OK, 1 row affected (0.09 sec) mysql> insert into tx values(6,6); Query OK, 1 row affected (31.60 sec)

这里,有2点需要注意:

1. A没有使用(select)表tx的时候,B仍然能够向tx表中插入数据;

2. A使用(select)表tx之后,B再进行insert操作,就会hang住,直到A表transaction结束。所以可以看到B的insert操作耗时31秒。当然了,也可能超时失败。

比如:

mysql> insert into tx values(10,10);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

以上这条语句,看起来是锁了整个表。但是其实深层次的目的,是为了保证事务的完整性,以及让A两次操作的REPEATABLE_READ;

比如 使用  select * from tx limit 1; 后面就仍然可以insert。因为不改变之前select的结果。

如果 select * from tx limit 10; 而最终只检出8条。这时候就不能insert,因为insert了的话,下次同样select得到的结果就不一样。

同理,如果select了某条记录,那么update同一条记录就不行,update其他的记录就可以。而且在事务中能够读到新更新的数据。

所以记住,事务的隔离级别的要求,只对事务过程中已经获取过的数据有关。跟没获取过、其他不可见的数据,无关。

Mysql数据库事务及隔离级别学习测试的更多相关文章

  1. Mysql数据库事务的隔离级别和锁的实现原理分析

    Mysql数据库事务的隔离级别和锁的实现原理分析 找到大神了:http://blog.csdn.net/tangkund3218/article/details/51753243 InnoDB使用MV ...

  2. MySQL数据库事务各隔离级别加锁情况--read uncommitted篇(转)

    本文转自https://m.imooc.com/article/details?article_id=17291,感谢作者 1.目的 1.1 合适人群 1.数据库事务特征我只是背过,并没有很深刻的理解 ...

  3. MySQL数据库事务各隔离级别加锁情况--read committed && MVCC(转载)

    http://www.imooc.com/article/17290 http://www.51testing.com/html/38/n-3720638.html https://dev.mysql ...

  4. MySQL数据库事务各隔离级别加锁情况--read committed && MVCC(转)

    本文转自https://m.imooc.com/article/details?article_id=17290 感谢作者 上篇记录了我对MySQL 事务 隔离级别read uncommitted的理 ...

  5. MySQL数据库事务各隔离级别加锁情况--Repeatable Read && MVCC(转)

    本文转自https://m.imooc.com/article/details?article_id=17289 感谢作者 上节回顾 上两篇记录了我对MySQL 事务 隔离级别read uncommi ...

  6. MySQL数据库事务各隔离级别加锁情况--read committed && MVCC

    之前已经转载过几篇相关的文章,此次基于mysql 5.7 版本,从测试和源码角度解释一下RR,RC级别为什么看到的数据不一样 先补充一下基础知识 基本知识 假设对于多版本(MVCC)的基础知识,有所了 ...

  7. 「DB」数据库事务的隔离级别

    *博客搬家:初版发布于 2017/04/10 00:37    原博客地址:https://my.oschina.net/sunqinwen/blog/875833 数据库事务的隔离级别 讲事务的隔离 ...

  8. Spring中事务的传播行为,7种事务的传播行为,数据库事务的隔离级别

    Propagation.REQUIRED 代表当前方法支持当前的事务,且与调用者处于同一事务上下文中,回滚统一回滚(如果当前方法是被其他方法调用的时候,且调用者本身即有事务),如果没有事务,则自己新建 ...

  9. 数据库事务ACID/隔离级别

    参考博客 1. 事务的定义 事务是用户定义的一个数据库操作序列.这些操作要么全执行,要么全不执行,是一个不可分割的工作单元.在关系型数据库中,事务可以是一条SQL语句,也可以是一组SQL语句或整个程序 ...

随机推荐

  1. Springboot以war包方式运行

    一.  修改打包形式 在pom.xml里设置 <packaging>war</packaging>   二.添加以下依赖  提供标记嵌入式servlet容器 <depen ...

  2. 快递鸟电子面单打印功能基于java

    之前的后天管理系统的电子面单打印使用的是灵通打单. 使用相对比较麻烦,需要到处Excel之后再导入,麻烦. 快递鸟有电子面单api,后台系统直接对接很是方便,不过也遇到了好些问题. 不难是不难,但是遇 ...

  3. OpenJudge——0003:jubeeeeeat

    OpenJudge——0003:jubeeeeeat 描述 众所周知,LZF很喜欢打一个叫Jubeat的游戏.这是个音乐游戏,游戏界面是4×4的方阵,会根据音乐节奏要求玩家按下一些指定方块(以下称co ...

  4. Win7/Win10下搭建Go语言开发环境

    1 下载适合window版本的Go安装包,下载地址http://code.google.com/p/go/downloads/list 2 下载适合window本本的LiteIDE,下载后解压即可使用 ...

  5. python2.7 关于打印中文的各种方法

    目录 str类型的中文 第一种姿势:逐个打印 第二种姿势: json dumps 第三种姿势: repr string_escape 第四种姿势:PEP3140 unicode类型的中文 当str与u ...

  6. SpringBoot静态资源目录

    在web开发中,静态资源的访问是必不可少的,如:图片.js.css 等资源的访问. SpringBoot对静态资源访问提供了很好的支持,基本使用默认配置就能满足开发需求. 在传统的web项目中静态资源 ...

  7. hdu 2121

    朱刘算法求无根最小树形图 可以任意选一个根,求最小的权和以及当时的根. 先建一个超级根,它连向所有点,边权为所有边的边权和加1(即sumw+1),然后求以它为根的最小树形图,再根据树形图权和与2*(s ...

  8. ASP.NET MVC HttpVerbs.Delete/Put Routes not firing

    原文地址: https://weblog.west-wind.com/posts/2015/Apr/09/ASPNET-MVC-HttpVerbsDeletePut-Routes-not-firing ...

  9. BZOJ 1191: [HNOI2006]超级英雄Hero 匈牙利算法

    1191: [HNOI2006]超级英雄Hero Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: xxx  Solved: 2xx 题目连接 http:/ ...

  10. Java中常见的IO流及其使用

    Java中IO流分成两大类,一种是输入流.全部的输入流都直接或间接继承自InputStream抽象类,输入流作为数据的来源.我们能够通过输入流的read方法读取字节数据.还有一种是输出流,全部的输出流 ...