MySQL 什么是事务?
该文为《 MySQL 实战 45 讲》的学习笔记,感谢查看,如有错误,欢迎指正
一、事务简介
事务就是为了保证一组数据库操作,要么全部成功,要么全部失败。
事务是在引擎层实现的,也就是说并不是所有引擎都可以使用事务,MyISAM 就不支持事务,这也是为什么会被 InnoDB 取代的原因。
说到事务,就不得不说 ACID 特性(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性)。
二、ACID 特性
2.1 原子性(Atomicity)
一个事务中的多组操作,要么全部成功,要么全部失败。在事务提交(commit)成功之后,所有的操作都生效,提交失败,所有的操作都会回滚。
2.2 一致性(Consistency)
一个事务执行之前和执行之后数据库都必须处于一致性状态。在事务执行的过程中,只要事务未提交,就不会改变数据库的状态。提交之后事务已完成,此时数据库状态发生变化。
2.3 隔离性(Isolation)
事务在执行过程中,是与外界完全隔离的,即使数据库发生了变更,事务中也获取不到。A 事务对数据库做的变更,在事务未提交之间,数据库中也看不到,B 事务中也看不到。
2.4 持久性(Durability)
事务一旦提交,对数据库的变更就会持久化到磁盘,即使数据库发生异常重启,数据也不会丢失。
三、隔离级别
当数据库出现有多个事务同时执行时,就可能出现脏读,幻读,不可重复读等问题,隔离级别就是为了解决这些问题的。隔离的越严实,效率就越低,并发越低,安全性越高。
隔离级别分为以下 4 种:
读未提交(read uncommitted,RU)
一个事务还未提交时,它做的变更就可以被别的事务看到。读提交(read committed,RC)
事务提交以后,它做的变更才能被其它事务看到。但是在这个事务未提交之前,数据库中发生的变更,这个事务也能看见。可重复度(repeatable read,RR)
事务总是只能看见在启动的那个时刻,数据库的状态。事务未提交之前做的变更,其它事务看不见。事务执行期间,数据库中已经发生的变更,这个事务也看不见。只能看见事务刚启动时刻,数据库的状态。串行化(serializable)
事务对某一行的操作会加锁,“写”会加“写锁”,“读”会加“读锁”,在锁释放掉之前,其它的事务都无法都这一行的记录进行操作。必须等之前的事务执行完毕,释放锁。后面的事务又会重新加锁。
我们通过一个例子来说明一下四种隔离级别具体是怎么体现的。
给出一个建表语句:
mysql> create table T(c int) engine=InnoDB;
mysql> insert into T(c) values(1);
假设有以下两个事务,其中执行的操作如图,从上至下是时间先后顺序:

在四种不同的隔离级别下,V1、V2、V3的值分别为多少呢?我们现在分析一下:
读未提交
读提交下,事务还未提交,做的变更就能被其它事务看见,因此事务 B 修改了值为 2 ,事务 A 可以直接看见。所以V1 = 2,V2 = 2,V3 = 2。读提交(RC)
读提交下,事务在提交之前,做的变更都无法被其它事务看见,但是事务本身可以看到数据库的变更。 因此,事务 B 做了修改以后,事务 A 无法立刻看见,V1 = 1,事务 B 提交以后,事务 A 就可以看到数据库的变更了,因此V2 = 2,V3 = 2。可重复读(RR)
事务总是只能看到在启动的那个时刻,数据库的状态,即在事务未提交之前,自己做的变更别的事务看不见,数据库中的变更自己也看不见。
因此,事务 B 提交之前,A 看不见 B 做的变更,V1 = 1,事务 B 提交以后,数据库的值虽然发生了变更,但是事务 A 还未提交,A 还是只能看到自己在启动时刻,数据库的值(可以理解为数据库有版本,只能看见历史版本)。因此,V2 = 1,事务 A 提交以后,就可以看到数据库的变更了,因此V3 = 2。串行化
串行化是指,事务在操作某一行记录时会加锁,“读”会加“读锁”,“写”会加“写锁”。
事务 A 在启动后,先执行了 1 条查询语句,对这行数据加了“读锁”,这个“读锁”要等事务 A 提交以后,才会释放。因此事务 B 执行查询语句会处于等待锁释放状态。这时候事务 B 会一直等待。因此,V1 = 1,V2 = 1,事务 A 提交之后,“读锁”释放,事务 B 获取该行记录的“读锁”,并更新了数据(又加了一个“写锁”),事务 B 未提交之前,A 再去查数据也需要等待锁释放,事务 B 提交以后,锁释放,A 拿到锁,开始查询数据,因此,V3 = 2。
以上是如何实现的呢?
四、事务隔离的实现原理
数据库中会创建一个视图,在“可重复读”隔离级别下,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图。在“读提交”隔离级别下,这个视图是在每个 SQL 语句开始执行的时候创建的。这里需要注意的是,“读未提交”隔离级别下直接返回记录上的最新值,没有视图概念;而“串行化”隔离级别下直接用加锁的方式来避免并行访问。
在 MySQL 中,实际上每条记录在更新的时候都会同时记录一条回滚操作。记录上的最新值,通过回滚操作,都可以得到前一个状态的值。同一条记录在系统中可以存在多个版本,就是数据库的多版本并发控制(MVCC)。
回滚日志什么时候删除呢,系统中没有比这个回滚日志更早的 read-view 时,这个回日志就会被删除。
因此不建议使用长事务,容易导致回滚日志太多,大量占用存储空间。
五、事务的启动方式
- 显式启动:
begin或start transaction。配套的提交语句是commit,回滚语句是rollback。 - 也可以使用
set autocommit=0,此时不需要显式启动,比如执行了一个select语句就直接启动了事务,但是需要再执行一条commit来提交;
因此建议设置set autocommit=1,此时需要用begin来开启事务,如果觉得多了一次交互,比较麻烦的话,也可以使用commit work and chain,表示提交当前事务,并且再启动一个新的事务,这样就只有一次begin了。
感谢阅读,有兴趣的小伙伴可以关注我的微信公众号DevOps探索之旅,大家一起学习进步

MySQL 什么是事务?的更多相关文章
- PHP mysql与mysqli事务详解
官方对PHP连接到MySQL数据库服务器的三种主要的API简介如下: http://php.net/manual/zh/mysqli.overview.php PHP mysql与mysqli事务详解 ...
- 【MySQL】漫谈MySQL中的事务及其实现
最近一直在做订单类的项目,使用了事务.我们的数据库选用的是MySQL,存储引擎选用innoDB,innoDB对事务有着良好的支持.这篇文章我们一起来扒一扒事务相关的知识. 为什么要有事务? 事务广泛的 ...
- MySQL数据库的事务管理
当前在开发ERP系统,使用到的数据库为Mysql.下面介绍下如何开启事务,以及事务隔离的机制 : 1. 检查当前数据库使用的存储引擎. show engines; 2. 修改前my.ini中的文件如下 ...
- MySQL存储过程之事务管理
原文链接:http://hideto.iteye.com/blog/195275 MySQL存储过程之事务管理 ACID:Atomic.Consistent.Isolated.Durable 存储程序 ...
- MySQL数据库分布式事务XA优缺点与改进方案
1 MySQL 外部XA分析 1.1 作用分析 MySQL数据库外部XA可以用在分布式数据库代理层,实现对MySQL数据库的分布式事务支持,例如开源的代理工具:ameoba[4],网易的DDB,淘宝的 ...
- 漫谈MySql中的事务
最近一直在做订单类的项目,使用了事务.我们的数据库选用的是MySql,存储引擎选用innoDB,innoDB对事务有着良好的支持.这篇文章我们一起来扒一扒事务相关的知识. 为什么要有事务? 事务广泛的 ...
- mysql中不同事务隔离级别下数据的显示效果--转载
事务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查询语句因为崩溃或其他原因而无法执行,那么所有的语句就都 ...
- 浅谈mysql中不同事务隔离级别下数据的显示效果
事务的概念 事 务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查 询语句因为崩溃或其他原因而无法执行,那 ...
- MySql中的事务嵌套
1.Mysql中的事务必须是InnoDB.Berkeley DB引擎,myisam不支持. 2.Mysql是不支持嵌套事务的,开启了一个事务的情况下,再开启一个事务,会隐式的提交上一个事务. 3.My ...
- MySQL中Procedure事务编写基础笔记
原文:MySQL中Procedure事务编写基础笔记 目录: 一.PROCEDURE: 二.CREATE PROCEDURE基本语法: 三.PROCEDURE小进阶 3.1.基本的DECLARE语 ...
随机推荐
- ASENET MVC 5 with Bootstrap and Knockout.js 第一弹
A Basic Example Now that the Knockout library is installed, let’s get right to an example of using ...
- 20191211 HNOI2017模拟赛 C题
题目: 分析: 开始觉得是神仙题... 然后发现n最多有2个质因子 这说明sm呢... 学过物理的小朋友们知道,当一个物体受多个不同方向相同的力时,只有相邻力的夹角相等,受力就会平衡 于是拆扇叶相当于 ...
- copy and swap技巧与移动赋值操作符
最近在实现一个Delegate类的时候碰到了一个问题,就是copy and swap技巧和移动赋值操作符有冲突. 比如有以下一个类: class Fun { public: Fun(const Fun ...
- 使用luabind绑定box2d的lua接口
最近在使用luabind绑定box2d的lua接口,发现不少问题.写在这里与大家分享. 1. body,fixture,joint的userdata.box2d的userdata的数据类型是void* ...
- RainbowPlan团队项目-总结
博客介绍 这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/GeographicInformationScience/ 这个作业要求在哪里 https:// ...
- Kdenlive-简单的操作
版权声明:原创文章,未经博主允许不得转载 前章:https://www.cnblogs.com/weilinfox/p/12246123.html 尽管是简单操作,但内容比较多.可以一边自己尝试编辑一 ...
- 异想家IDEA的偏好配置
最好将配置文件位置改为软件安装目录下,因为只有自己用,易于便携. 修改bin目录下的idea.properties,注释#去掉修改idea.config.path.idea.system.path配置 ...
- oc---类方法load和initialize的区别
在iOS开发中,就像Application有生命周期回调方法一样,在Objective-C的类被加载和初始化的时候,也可以收到方法回调,可以在适当的情况下做一些定制处理.而这正是本篇文章所要介绍的lo ...
- Python - Unittest小结
一.Unittest 单元测试框架,可用于自动化测试用力组织,执行,输出结果 二.Unittest构成 Test Case Test Suite Test Fixture Test Runner (图 ...
- 工作流Activity框架入门(一)
Activity工作流入门 1. 工作流概念 工作流(Workflow),就是"业务过程的部分或整体在计算机应用环境下的自动化",它主要解决的是"使在多个参与者之间按照某 ...