mysql InnoDB 引擎下事物学习

建表user

CREATE TABLE `user` (
`uid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`uname` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`upass` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`money` decimal(10,2) DEFAULT NULL,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;

插入数据

INSERT INTO `user` (`uid`, `uname`, `upass`, `money`)
VALUES
(1, 'user1', 'admin123', 1000.00),
(2, 'user2', 'admin123', 1000.00);

如图:

为了说明问题,我们打开两个控制台分别进行登录来模拟两个用户(暂且成为用户A和用户B吧),并设置当前MySQL会话的事务隔离级别。

一. read uncommitted(读取未提交数据)

具体用户A的操作如下:

set session transaction isolation level read uncommitted;
start transaction;
select * from user;

结果如下:

用户B的操作如下:

set session transaction isolation level read uncommitted;
start transaction;
update user set money=money+200 where uid = 1;

随后我们在A用户中查询数据,结果如下:

结论一:

我们将事务隔离级别设置为read uncommitted,即便是事务没有commit,但是我们仍然能读到未提交的数据,这是所有隔离级别中最低的一种。

那么这么做有什么问题吗?

那就是我们在一个事务中可以随随便便读取到其他事务未提交的数据,这还是比较麻烦的,我们叫脏读。

但是数据库的数据没有改变。因为只有事务commit后才会更新到数据库。

二. read committed(可以读取其他事务提交的数据)---大多数数据库(Oracle)默认的隔离级别

同样的办法,我们将用户AB所在的会话当前事务隔离级别设置为read commited。

set session transaction isolation level read committed;
start transaction;

在用户A所在的会话中我们执行下面操作:

update user set money=money-200 where uid=1;

结果如下:

我们将uid=1的用户user1减200。然后查询,发现uid=1的用户money变为800。

在B用户所在的会话中查询:

select * from user;

结果如下:

 

我们会发现数据并没有变,还是1000。

接着在会话A中我们将事务提交:

commit;

结果如下:

结论二:

当我们将当前会话的隔离级别设置为read committed的时候,当前会话只能读取到其他事务提交的数据,未提交的数据读不到。

那么这么做有什么问题吗?

那就是我们在会话B同一个事务中,读取到两次不同的结果。这就造成了不可重复读,就是两次读取的结果不同。这种现象叫不可重复读。

三. repeatable read(可重读)---MySQL默认的隔离级别

现在有个需求,同一个事务中查询结果必须保持一致,如果你是数据库,你会怎么做?数据库是这么做的。

在会话B中我们当前事务隔离级别为repeatable read。具体操作如下:

set session transaction isolation level repeatable read;
start transaction;

接着在会话B中查询数据:

我们在A用户所在会话中为表account添加一条数据,然后我们查询看数据插入是否成功:

回到B用户所在的会话,我们查询结果:

用户B在他所在的会话中想插入一条新数据uid=3,money=1000。来我们操作下:

键'PRIMARY'重复输入'3',用户B看到的数据只有两条,插入是却提示主键重复。再次查询:

依旧还是两条数据。

结论三:

当我们将当前会话的隔离级别设置为repeatable read的时候,当前会话可以重复读,就是每次读取的结果集都相同,而不管其他事务有没有提交。

要一个事务中读取的数据一致(可重复读)。数据已经发生改变,但是我还是要保持一致。但是,出现了用户B面对的问题,这种现象叫幻读。

四. serializable(串行化)

同样,我们将用户B所在的会话的事务隔离级别设置为serializable并开启事务。

set session transaction isolation level serializable;
start transaction;

在用户B所在的会话中我们执行下面操作:

那我们这个时候在用户A所在的会话中写数据呢?

我们发现用户A所在的会话陷入等待,如果超时(这个时间可以进行配置),会出现Lock wait timeout提示:

超过锁定等待超时; 尝试重新启动事务

如果在等待期间我们用户B所在的会话事务提交,那么用户A所在的事务的写操作将提示操作成功。

结论四:

当我们将当前会话的隔离级别设置为serializable的时候,其他会话对该表的写操作将被挂起。可以看到,这是隔离级别中最严格的,但是这样做势必对性能造成影响。所以在实际的选用上,我们要根据当前具体的情况选用合适的。

以下附带一个简单描述版本。

事务的隔离级别分为:未提交读(read uncommitted)、已提交读(read committed)、可重复读(repeatable read)、串行化(serializable)。

未提交读

未提交读的意思就是比如原先name的值是小刚,然后有一个事务B`update table set name = '小明' where id = 1`,它还没提交事务。同时事务A也起了,有一个select语句`select name from table where id = 1`,在这个隔离级别下获取到的name的值是小明而不是小刚。那万一事务B回滚了,实际数据库中的名字还是小刚,事务A却返回了一个小明,这就称之为脏读。

已提交读

按照上面那个例子,在已提交读的情况下,事务A的select name 的结果是小刚,而不是小明,因为在这个隔离级别下,一个事务只能读到另一个事务修改的已经提交了事务的数据。但是有个现象,还是拿上面的例子说。如果事务B 在这时候隐式提交了时候,然后事务A的select name结果就是小明了,这都没问题,但是事务A还没结束,这时候事务B又`update table set name = '小红' where id = 1`并且隐式提交了。然后事务A又执行了一次`select name from table where id = 1`结果就返回了小红。这种现象叫不可重复读。

可重复读

可重复读就是一个事务只能读到另一个事务修改的已提交了事务的数据,但是第一次读取的数据,即使别的事务修改的这个值,这个事务再读取这条数据的时候还是和第一次获取的一样,不会随着别的事务的修改而改变。这和已提交读的区别就在于,它重复读取的值是不变的。所以取了个贴切的名字叫可重复读。按照这个隔离级别下那上面的例子就是:

串行化

上面三个隔离级别对同一条记录的读和写都可以并发进行,但是串行化格式下就只能进行读-读并发。只要有一个事务操作一条记录的写,那么其他要访问这条记录的事务都得等着。

Mysql InnoDB引擎下 事务的隔离级别的更多相关文章

  1. MySQL/MariaDB数据库的事务和隔离级别

      MySQL/MariaDB数据库的事务和隔离级别 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.事务概述 1>.事务Transactions 一组原子性的SQL语句 ...

  2. MySQL innodb引擎下根据.frm和.ibd文件恢复表结构和数据

    记录通过.frm和.ibd文件恢复数据到本地 .frm文件:保存了每个表的元数据,包括表结构的定义等: .ibd文件:InnoDB引擎开启了独立表空间(my.ini中配置innodb_file_per ...

  3. MySQL(八)事务的隔离级别

    一.事务的并发问题 1.脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据 2.不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并 ...

  4. MySQL数据库事务的四大特性以及事务的隔离级别

    一.事务的四大特性(ACID) 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: 1.原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因 ...

  5. 数据库事务的四大特性以及事务的隔离级别(mysql)

      本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指 ...

  6. MySQL事务的隔离级别

    为什么需要隔离 当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种 ...

  7. 高性能MySQL--innodb中事务的隔离级别与锁的关系

    最近买了<高性能MySQL>这本书回来看,从中收益颇多!我来一吐为快! 我们都知道事务,那么在什么情况下我们需要使用事务呢? 银行应用是解释事务的一个经典例子.假设一个银行的数据库有两张表 ...

  8. 数据库事务的四大特性以及事务的隔离级别-与-Spring事务传播机制&隔离级别

    数据库事务的四大特性以及事务的隔离级别   本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ ...

  9. 数据库事务的四大特性以及4种事务的隔离级别-以及对应的5种JDBC事务隔离级别

    本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指事务 ...

随机推荐

  1. Flink 从0到1学习 —— Flink 中如何管理配置?

    前言 如果你了解 Apache Flink 的话,那么你应该熟悉该如何像 Flink 发送数据或者如何从 Flink 获取数据.但是在某些情况下,我们需要将配置数据发送到 Flink 集群并从中接收一 ...

  2. 【Java例题】2.2 分数类

    2.定义分数类,包括分子和分母变量.构造方法. 加减乘除方法.化简方法.值计算方法和显示分子和分母的方法. 然后编写一个主类,在其主方法中通过定义两个分数对象来 显示每一个分数的分子值.分母值.化简和 ...

  3. 消息中间件-activemq实战整合Spring之Topic模式(五)

    这一节我们看一下Topic模式下的消息发布是如何处理的. applicationContext-ActiveMQ.xml配置: <?xml version="1.0" enc ...

  4. 常见Http协议状态码

    收集常见的http协议状态码,供查阅!包括中文和英文对照. 中文版 1**:请求收到,继续处理 2**:操作成功收到,分析.接受 3**:完成此请求必须进一步处理 4**:请求包含一个错误语法或不能完 ...

  5. C# 基于NPOI+Office COM组件 实现20行代码在线预览文档(word,excel,pdf,txt,png)

    由于项目需要,需要一个在线预览office的功能,小编一开始使用的是微软提供的方法,简单快捷,但是不符合小编开发需求, 就另外用了:将文件转换成html文件然后预览html文件的方法.对微软提供的方法 ...

  6. 对博弈活动中蕴含的信息论原理的讨论,以及从熵角度看不同词素抽象方式在WEBSHELL文本检测中的效果区别

    1. 从赛马说起 0x1:赛马问题场景介绍 假设在一场赛马中有m匹马参赛,令第i匹参赛马获胜的概率为pi,如果第i匹马获胜,那么机会收益为oi比1,即在第i匹马上每投资一美元,如果赢了,会得到oi美元 ...

  7. 自己实现spring核心功能 一

    聊聊spring spring对于java开发者来说,是最熟悉不过的框架了,我们日常开发中每天都在使用它.它有着各种各样的好处,简单易用,得心应手... ... 我们一说到spring就会讲到ioc ...

  8. Windows Server 2008在网络环境配置打印机

    下面学习在Windows Server2008在网络环境搭建打印机服务器,打印机服务器也是很常用的,特别是在中大型企业里面,打印机数量比较多为方便管理,可以搭建一个打印机服务,这里介绍一下,本地打印机 ...

  9. [HEOI2013]SAO(树上dp,计数)

    [HEOI2013]SAO (这写了一个晚上QAQ,可能是我太蠢了吧.) 题目说只有\(n-1\)条边,然而每个点又相互联系.说明它的结构是一个类似树的结构,但是是有向边连接的,题目问的是方案个数,那 ...

  10. linux环境部署,docker如何安装redis

    安装步骤 1. 安装Redis 通过docker search redis和docker pull redis下载redis镜像 2. 新建挂载配置文件夹 新建data和conf两个文件夹,位置随意. ...