登录mysql:

mysql -u root -p123456

Mysql 版本号

mysql> select version();
+-------------------------+
| version() |
+-------------------------+
| 5.6.31-0ubuntu0.15.10.1 |
+-------------------------+
1 row in set (0.06 sec) mysql>

查看InnoDB存储引擎 系统级的隔离级别 和 会话级的隔离级别

mysql> select @@global.tx_isolation,@@tx_isolation;
+-----------------------+-----------------+
| @@global.tx_isolation | @@tx_isolation |
+-----------------------+-----------------+
| REPEATABLE-READ | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.07 sec) mysql>

更改会话级的隔离级别

mysql> set session tx_isolation='read-uncommitted';
Query OK, 0 rows affected (0.08 sec) mysql> select @@global.tx_isolation,@@tx_isolation;
+-----------------------+------------------+
| @@global.tx_isolation | @@tx_isolation |
+-----------------------+------------------+
| REPEATABLE-READ | READ-UNCOMMITTED |
+-----------------------+------------------+
1 row in set (0.00 sec) mysql>

打开两个mysql连接:

在第一个连接中设置不同隔离级别,然后在两个连接上查看设置结果:

session1:

mysql> set session tx_isolation='read-uncommitted';
Query OK, 0 rows affected (0.08 sec) mysql> select @@global.tx_isolation,@@tx_isolation;
+-----------------------+------------------+
| @@global.tx_isolation | @@tx_isolation |
+-----------------------+------------------+
| REPEATABLE-READ | READ-UNCOMMITTED |
+-----------------------+------------------+
1 row in set (0.00 sec) mysql>

session2:

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

更改系统级的隔离级别

session1:

mysql>  set global tx_isolation='read-uncommitted';
Query OK, 0 rows affected (0.00 sec) mysql> select @@global.tx_isolation, @@tx_isolation;
+-----------------------+------------------+
| @@global.tx_isolation | @@tx_isolation |
+-----------------------+------------------+
| READ-UNCOMMITTED | READ-UNCOMMITTED |
+-----------------------+------------------+
1 row in set (0.00 sec) mysql>

session2:

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

关闭SQL语句的自动提交

mysql> set autocommit=off;
Query OK, 0 rows affected (0.04 sec) mysql>

查看SQL语句自动提交是否关闭

mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | OFF |
+---------------+-------+
1 row in set (0.16 sec) mysql>

建立实验表

mysql> create table tao (col1 tinyint unsigned, col2 varchar(20), primary key(col1));
Query OK, 0 rows affected (0.14 sec) mysql> show create table tao \G;
*************************** 1. row ***************************
Table: tao
Create Table: CREATE TABLE `tao` (
`col1` tinyint(3) unsigned NOT NULL DEFAULT '',
`col2` varchar(20) DEFAULT NULL,
PRIMARY KEY (`col1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec) ERROR:
No query specified mysql>

1、演示脏读

session1:

mysql> use duan;
Database changed
mysql> select @@global.tx_isolation, @@tx_isolation;
+-----------------------+------------------+
| @@global.tx_isolation | @@tx_isolation |
+-----------------------+------------------+
| READ-UNCOMMITTED | READ-UNCOMMITTED |
+-----------------------+------------------+
1 row in set (0.00 sec) mysql> set autocommit=off;
Query OK, 0 rows affected (0.00 sec) mysql> create table tao (col1 tinyint unsigned, col2 varchar(20), primary key(col1));
Query OK, 0 rows affected (0.05 sec) mysql> start transaction;
Query OK, 0 rows affected (0.00 sec) mysql> insert into tao values(1,'');
Query OK, 1 row affected (0.00 sec) mysql>

session2:

mysql> use duan;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A Database changed
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set (0.00 sec) mysql> select * from tao;
+------+------+
| col1 | col2 |
+------+------+
| 1 | 2017 |
+------+------+
1 row in set (0.00 sec) mysql>

1.1、场景1: 演示脏读(未提交的数据被读到)read-uncommitted

下面所有的session1和session2都是分别是一个独立的事务。

1.2、场景2(不演示)

1、session1查询tao表,session2更新tao表里的一条记录,但未提交。

2、session1在同一个事务内再查询tao表时,发现结果已经改变。

3、session2回滚后,session1再查询时,结果已经变回去了。

1.3、场景3(read-uncommitted)

1、session1查询tao表,session2更新tao表里的一条记录,但未提交。

2、session1在同一个事务内再查询tao表时,发现结果已经改变。(可读)

3、session1同时修改相同的记录行(id=2),修改不成功。(不可修改)

结论:可以看出READ-UNCOMMITTED隔离级别,当两个事务同时进行时,即使事务没有提交,所做的修改也会对事务内的查询做出影响,这种级别显然很不安全。但是在表对某行进行修改时,会对该行加上行共享锁。

更改隔离级别为Read Committed后,不存在脏读的问题。

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

2、演示不可重复读

(正确应该是:一个会话中的两次查询,返回结果应该一样。)

2.2、场景2:

1、session1开启一个事务,查询tao表;

2、session2开启一个新事务,修改tao表的某条记录;

3、session1重复查询,记录没有变化;

4、session2提交后,session1再重复查询时,记录有变化。

2.3、场景3

1、session1开启一个新的事务修改id=2的记录,成功。

2、session2开启一个新的事务,修改id=2的记录,失败。(行共享锁)

3、session2开启一个新的事务,修改id=3的记录,成功。

总结:READ-COMMITTED事务隔离级别,只有在事务提交后,才会对另一个事务产生影响,并且在对表进行修改时,会对表数据行加上行共享锁。

更改隔离级别为Repeatable Read后,不存在不可重复读的问题。

mysql> set global tx_isolation='repeatable-read';
Query OK, 0 rows affected (0.01 sec) mysql> set session tx_isolation='repeatable-read';
Query OK, 0 rows affected (0.00 sec) mysql> select @@global.tx_isolation, @@tx_isolation;
+-----------------------+-----------------+
| @@global.tx_isolation | @@tx_isolation |
+-----------------------+-----------------+
| REPEATABLE-READ | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec) mysql>

3、幻读

3.1、场景1(一个事务被另一个事务已提交的insert数据所影响)

3.2、场景2

1、session1开启一个新事务,并查询一次。

2、session2开启一个新事务,并对id=4进行一次修改,修改成功。

3、session1重复查询一次,结果没有变化。

4、session2提交

5、session1再查询一次,结果没有变化。

6、session1提交事务后,再查询时记录发生变化。

3.3、场景3

1、session1开启一个新的事务修改id=2的记录,成功。

2、session2开启一个新的事务,修改id=2的记录,失败。(行共享锁)

3、session2开启一个新的事务,修改id=3的记录,成功。

总结:REPEATABLE-READ事务隔离级别,当两个事务同时进行时,其中一个事务修改数据对另一个事务不会造成影响,即使修改的事务已经提交也不会对另一个事务造成影响。

  在事务中对某条记录修改,会对记录加上行共享锁,直到事务结束才会释放。

更改隔离级别为完全串行化 Serializable 后,不存在幻读的问题。

mysql> set global tx_isolation='serializable';
Query OK, 0 rows affected (0.00 sec) mysql> set session tx_isolation='serializable';
Query OK, 0 rows affected (0.00 sec)

在这种情况下,只允许一个事务在执行,其它事务必须等待这个事务执行完后才能执行。没有并发,只是单纯的串行。

4、串行化

4.1、场景1

1、session1开启一个新事务,并作一次查询

2、session2对表进行查询,正常得出结果,可知对user表的查询是可以进行的

3、session2开始事务,并对记录做修改,因为A事务未提交,所以session2的修改处于等待状态,等待session1事务结束,最后超时,说明session1在对tao表做查询操作后,对表加上了共享锁。(实验结果,session2 update成功。不知道是不是mysql版本问题?)

结论:READ-COMMITTED事务隔离级别,只有在事务提交后,才会对另一个事务产生影响,并且在对表进行修改时,会对表数据行加上行共享锁。

这块的总结见:《事务之一:数据库事务基础知识回顾

mysql事务之二:MySQL隔离级别演示的更多相关文章

  1. 粗谈MySQL事务的特性和隔离级别

    网上对于此类的文章已经十分饱和了,那还写的原因很简单--作为自己的理解笔记. 前言 ​  此篇文章作为自己学习MySQL的一些个人理解,使用的引擎是InnoDb.首先先讲讲事务的概念,在<高性能 ...

  2. MySQL事务及实现、隔离级别及锁与优化

    事务  事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.事务是逻辑上的一组操作,要么都执行,要么都不执行. ACID简介 原子性(Atomicity) ...

  3. MySQL事务的四种隔离级别

    事务的基本要素: 原子性(atomicity):事务开始后的全部操作, 要么全部执行成功,如果中间出现错误,事务回滚到事务开始前的状态. 一致性(Consistency):事务开始后,数据库的完整性约 ...

  4. Mysql加锁过程详解(6)-数据库隔离级别(2)-通过例子理解事务的4种隔离级别

    Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...

  5. mysql 事务,锁,隔离机制

    mysql架构 锁 为了解并发问题,引入锁,mysql中锁分为读锁和写锁,即share lock和exclusive lock.故名思义,share lock之间不互斥,share lock和excl ...

  6. 数据库操作事物的四大特性以及MySQL数据库的四种隔离级别

    1 .事物操作数据库的四大特性(ACID) 1.原子性 (Atomicity) 原子性:就是事物的所包含的所有操作,要么全部成功,要么全部失败回滚. 2.一致性 (Consistency) 一致性:简 ...

  7. Spring中的事务传播行为与隔离级别

    事务传播行为 事务传播行为(为了解决业务层方法之间互相调用的事务问题): 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播.例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己 ...

  8. Spring事务传播机制与隔离级别(转)

    Spring事务传播机制与隔离级别 博客分类: Spring   转自:http://blog.csdn.net/edward0830ly/article/details/7569954 (写的不错) ...

  9. spring事务传播属性和隔离级别

    猫咪咪的Java世界 spring事务传播属性和隔离级别 博客分类: Spring java编程   1 事务的传播属性(Propagation) 1) REQUIRED ,这个是默认的属性 Supp ...

随机推荐

  1. Java中的赋值运算符

    赋值运算符是指为变量或常量指定数值的符号.如可以使用 “=” 将右边的表达式结果赋给左边的操作数. Java 支持的常用赋值运算符,如下表所示: public class HelloWorld{ pu ...

  2. NumPy数据类型

    NumPy - 数据类型 NumPy 支持比 Python 更多种类的数值类型. 下表显示了 NumPy 中定义的不同标量数据类型. 序号 数据类型及描述 1. bool_存储为一个字节的布尔值(真或 ...

  3. NiceFish的ERROR in AppModule is not an NgModule问题

    大漠老师的angular2新手教程项目,nicefish刚开始下下来运行ng serve --prod --aot 是 出现ERROR in AppModule is not an NgModule ...

  4. 入门教程:.NET开源OpenID Connect 和OAuth解决方案IdentityServer v3 术语(二)

    你应该知道的在文档和对象模型中使用一些特定的术语: OpenID Connect Provider (OP) 授权服务器 Thinktecture IdentityServer v3 是一个.NET ...

  5. TextView实现图文混合编排

    TextView实现图文混合编排 一.简介 在这里实现图文混合编排使用的是:TextView中预定义的类似Html的标签 二.方法 * 1.设置好html标签的文本 String html=" ...

  6. js & jquery数组介绍

    (转自:http://www.jb51.net/article/30793.htm) 1.数组的创建 var arr=new Array(); 2.查找数组中的元素 for(var i=0;i< ...

  7. Android中UI线程与后台线程交互设计的6种方法

    在android的设计思想中,为了确保用户顺滑的操作体验.一些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必须要重新开启 一个后台线程运行这些任务.然而,往往这些任务最终又会直 ...

  8. 一步一步写jQuery插件

    转载自:http://www.cnblogs.com/joey0210/p/3408349.html 前言 如今做web开发,jquery 几乎是必不可少的,就连vs神器在2010版本开始将Jquer ...

  9. [置顶] Git 配置SSH简单玩法?

    > 第一步下载git点击直接下载 他会检测您的系统当前是64bit还是32bit安装过程不再啰嗦反正就是Next Next Next Finish 第二步这里你可以下载TortoiseGit点击 ...

  10. HAWQ取代传统数仓实践(十八)——层次维度

    一.层次维度简介 大多数维度都具有一个或多个层次.例如,示例数据仓库中的日期维度就有一个四级层次:年.季度.月和日.这些级别用date_dim表里的列表示.日期维度是一个单路径层次,因为除了年-季度- ...