事务是逻辑上的一组操作,要么都执行,要么都不执行。

事务最经典的、经常被拿出来说的例子就是转账了。假如小花要给小白转账1000元,这个转账会涉及到两个关键操作就是:将小花的余额-1000,将小白的余额+1000。但是万一在这两个操作之间突然出现了错误,比如银行系统突然断电,或突然宕机崩溃,都可能会导致小花的余额-1000之后,小白的余额却没有+1000,这样小花和小白就都不开心了。事务就是为了保证这两个关键操作要么都成功,要么都要失败的一个机制,都成功也就完成了转账,都失败也不会造成小花的损失。

事务的特性

事务是有四个特性(ACID)的,分别是原子性、一致性、隔离性和持久性。

原子性(Atomity): 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用。

一致性(Consistency): 执行事务的前后,数据保持一致。

隔离性(Isolation): 并发访问数据库时,一个用户的事务不能被其他事务所干扰,各个并发事务对于数据库来说都是独立的。

持久性(Durable):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

并发事务带来的问题

在典型的应用程序中,如果是多个事务并发运行,经常会出现多个事务操作相同的数据来完成各自的任务(多个用户对统一数据进行操作)的场景。

虽然并发是必须的,但却可能会导致以下的问题。

1.脏读(Dirty Read)

当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,而这个数据可能最后并不会被提交到数据库中,那么另外一个事务读到的这个数据是【脏数据】,依据【脏数据】所做的操作就可能是不正确的。

2.丢失修改(Lost to Modify)

在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样就可能会导致第一个事务内的修改结果被丢失,因为实际上最终生效的修改是第二个事务做的修改,这就是丢失修改。例如,事务1读取了某表中的数据A=21,事务2也读取的是A=21,当事务1修改了A=A-1,事务2也修改了A=A-1,可是最终的结果是A=20,事务1的修改被丢失。

3.不可重复读(Unrepeatableread)

不可重复读指的是在一个事务内多次读取同一数据,这前后两次读取的数据却不一致的情况。因为在这个事务还没有结束时,可能会有另一个事务也访问该数据,可能会造成在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据不一样的问题。在同一个事务内两次读到的数据不一样的情况,被称为不可重复读。

4.幻读(Phantom Read)

幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。

不可重复度和幻读的区别

不可重复读的重点是修改,强调的是记录的状态,比如记录中的一些属性;幻读的重点在于新增或者删除,强调的是记录的数量,比如多了几条记录或少了几条记录。

不可重复读的例子(同样的条件,你读取过的数据,再次读取出来发现值不一样了):事务1中的A先生读取自己的余额为1000的操作还没完成,事务2中的B先生就修改了A先生的余额为2000,导致A先生再次读自己的余额时余额变为了2000,这就是不可重复读。

幻读的例子(同样的条件,第1次和第2次读出来的记录数不一样):假如工资单表中工资大于1W的有24人,事务1读取了所有工资大于1W的人,共查到24条记录,而这时事务2又插入了一条工资大于1W的记录,事务1再次读取时查到的记录就变为了25条,这样就导致了幻读。

事务隔离级别

在的SQL标准中定义了四个隔离级别,分别是读取未提交、读取已提交、可重读和可串行化。

读取未提交(READ-UNCOMMITTED):最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。

读取已提交(READ-COMMITTED):允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

可重读(REPEATABLE-READ):对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

可串行化(SERIALIZABLE):最高的隔离级别,完全服从ACID四个特性。在这个隔离级别下,所有的事务是依次逐个执行,严格保证事务之间完全不可能产生干扰。这就意味着,这个级别可以有效防止脏读、不可重复读以及幻读。

MySQL中的InnoDB存储引擎的默认使用的隔离级别是REPEATABLE-READ(可重读)。

SELECT @@tx_isolation;

通过上面的命令可以查询出当前MySQL使用的隔离级别。

这里需要注意,MySQL对隔离级别的实现与SQL标准不同的地方在于InnoDB存储引擎在REPEATABLE-READ(可重读)事务隔离级别下使用的是Next-Key Lock锁算法,因此可以避免幻读的产生,这与其他数据库系统(如 SQL Server)是不同的。这也意味着InnoDB存储引擎的默认隔离级别REPEATABLE-READ(可重读)已经可以完全保证事务的隔离性要求,即达到了SQL标准的SERIALIZABLE(可串行化)隔离级别。

我们知道,数据库的隔离级别通常是使用锁来实现的。隔离级别越低,事务请求的锁也就越少,造成的性能损失也就越低,数据库响应也就越快,所以大部分数据库系统的隔离级别都是READ-COMMITTED(读取已提交内容)。但是你要知道的是,MySQL的InnoDB存储引擎默认使用的REPEATABLE-READ(可重读)并不会有任何性能损失(真的吗),因为MySQL做了一些相应的优化。另外,InnoDB存储引擎在分布式事务的情况下一般会用到SERIALIZABLE(可串行化)隔离级别,这是场景的特殊性决定的。

事务相关命令

在MySQL命令行的默认配置中,事务都是自动提交的,即执行SQL语句后就会马上执行COMMIT操作。

我们可以通过下面的命令来设置隔离级别。

SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]

另外还有一些并发控制语句,也是开发中经常会使用到的。

START TARNSACTION | BEGIN -- 显式地开启一个事务
COMMIT -- 提交事务,使得对数据库做的所有修改成为永久性
ROLLBACK -- 回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。

"我不记得回家的路,我只记得下雨了我怕你淋着。"

mysql中的事务隔离级别的更多相关文章

  1. 在MySQL中设置事务隔离级别有2种方法:

    在MySQL中设置事务隔离级别有2种方法: 1 在my.cnf中设置,在mysqld选项中如下设置 [mysqld] transaction-isolation = READ-COMMITTED 2 ...

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

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

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

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

  4. 重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系

    重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系 Innodb中的事务隔离级别和锁的关系 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁 ...

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

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

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

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

  7. MySQL事物(一)事务隔离级别和事物并发冲突

    数据库的操作通常为写和读,就是所说的CRUD:增加(Create).读取(Read).更新(Update)和删除(Delete).事务就是一件完整要做的事情.事务是恢复和并发控制的基本单位.事务必须始 ...

  8. MySQL四种事务隔离级别详解

    本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做 ...

  9. Innodb中的事务隔离级别和锁的关系(转载)

    nodb中的事务隔离级别和锁的关系 原文:https://tech.meituan.com/innodb-lock.html ameng ·2014-08-20 15:50 前言: 我们都知道事务的几 ...

随机推荐

  1. MySQL使用可重复读作为默认隔离级别的原因

    一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle.SQL Server等,而MySQL却使用可重复读(Read-Repeatable,RR). ...

  2. ansible部署Tomcat

    首先要准备的环境就是免密登录 这是要在ansible-playbook中所写的内容---- hosts: tomcat tasks:   - name: 关闭防火墙     service: name ...

  3. vue+element 中 el-input框 限制只能输入数字及一位小数

    仅个人经验,希望能帮到有需要的人. 第一次写 就话不多说了直接上代码. <el-input @keyup.native="proving(index)" v-model=&q ...

  4. 使用 API 网关构建微服务-2

    「Chris Richardson 微服务系列」使用 API 网关构建微服务 Posted on 2016年5月12日 编者的话|本文来自 Nginx 官方博客,是微服务系列文章的第二篇,本文将探讨: ...

  5. SpringBoot IoC启动流程、初始化过程及Bean生命周期各个阶段的作用

    目录 SpringBoot IoC启动流程.初始化过程及Bean生命周期各个阶段的作用 简述 首先明确IoC容器是啥 准备-SpringApplication的实例化 启动-SpringApplica ...

  6. [ASP.NET Core 3框架揭秘] 依赖注入[4]:一个Mini版的依赖注入框架

    在前面的章节中,我们从纯理论的角度对依赖注入进行了深入论述,我们接下来会对.NET Core依赖注入框架进行单独介绍.为了让读者朋友能够更好地理解.NET Core依赖注入框架的设计与实现,我们按照类 ...

  7. UWP 从创建到发布流程一栏

    # UWP的产品新建到发布流程一览 1,UWP开发特性 U: Universal(通用) W: Windows P: Plantform(平台) 运行在Windows10设备 比WPF更加多样化和完善 ...

  8. 无法Google的解决方案

    献给新入开发行业的小伙伴. 本文不会事无巨细的讲解每一个细节,只是为读者提供一个路线图,并提供相应的参考资料. 为了更高效的解决各种技术问题,有时不得不到墙外去寻找解决方案.每个开发者效率高了,宏观来 ...

  9. Java中往zip压缩包追加文件

    有个需求,从某个接口下载的一个zip压缩包,往里面添加一个说明文件.搜索了一下,没有找到往zip直接添加文件的方法,最终解决方法是先解压.再压缩. 具体过程如下: 1.一个zip文件的压缩和解压工具类 ...

  10. java正则表达式大全(常用)

    一.校验数字的表达式 数字:^[-]*$ n位的数字:^\d{n}$ 至少n位的数字:^\d{n,}$ m-n位的数字:^\d{m,n}$ 零和非零开头的数字:^(|[-][-]*)$ 非零开头的最多 ...