该文为《 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);

假设有以下两个事务,其中执行的操作如图,从上至下是时间先后顺序:



在四种不同的隔离级别下,V1V2V3的值分别为多少呢?我们现在分析一下:

  1. 读未提交

    读提交下,事务还未提交,做的变更就能被其它事务看见,因此事务 B 修改了值为 2 ,事务 A 可以直接看见。所以 V1 = 2V2 = 2V3 = 2

  2. 读提交(RC)

    读提交下,事务在提交之前,做的变更都无法被其它事务看见,但是事务本身可以看到数据库的变更。 因此,事务 B 做了修改以后,事务 A 无法立刻看见,V1 = 1,事务 B 提交以后,事务 A 就可以看到数据库的变更了,因此 V2 = 2V3 = 2

  3. 可重复读(RR)

    事务总是只能看到在启动的那个时刻,数据库的状态,即在事务未提交之前,自己做的变更别的事务看不见,数据库中的变更自己也看不见。

    因此,事务 B 提交之前,A 看不见 B 做的变更,V1 = 1,事务 B 提交以后,数据库的值虽然发生了变更,但是事务 A 还未提交,A 还是只能看到自己在启动时刻,数据库的值(可以理解为数据库有版本,只能看见历史版本)。因此,V2 = 1,事务 A 提交以后,就可以看到数据库的变更了,因此 V3 = 2

  4. 串行化

    串行化是指,事务在操作某一行记录时会加锁,“读”会加“读锁”,“写”会加“写锁”。

    事务 A 在启动后,先执行了 1 条查询语句,对这行数据加了“读锁”,这个“读锁”要等事务 A 提交以后,才会释放。因此事务 B 执行查询语句会处于等待锁释放状态。这时候事务 B 会一直等待。因此,V1 = 1V2 = 1,事务 A 提交之后,“读锁”释放,事务 B 获取该行记录的“读锁”,并更新了数据(又加了一个“写锁”),事务 B 未提交之前,A 再去查数据也需要等待锁释放,事务 B 提交以后,锁释放,A 拿到锁,开始查询数据,因此,V3 = 2

以上是如何实现的呢?

四、事务隔离的实现原理

数据库中会创建一个视图,在“可重复读”隔离级别下,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图。在“读提交”隔离级别下,这个视图是在每个 SQL 语句开始执行的时候创建的。这里需要注意的是,“读未提交”隔离级别下直接返回记录上的最新值,没有视图概念;而“串行化”隔离级别下直接用加锁的方式来避免并行访问。

在 MySQL 中,实际上每条记录在更新的时候都会同时记录一条回滚操作。记录上的最新值,通过回滚操作,都可以得到前一个状态的值。同一条记录在系统中可以存在多个版本,就是数据库的多版本并发控制(MVCC)。

回滚日志什么时候删除呢,系统中没有比这个回滚日志更早的 read-view 时,这个回日志就会被删除。

因此不建议使用长事务,容易导致回滚日志太多,大量占用存储空间。

五、事务的启动方式
  • 显式启动:beginstart transaction。配套的提交语句是 commit,回滚语句是 rollback
  • 也可以使用 set autocommit=0,此时不需要显式启动,比如执行了一个select语句就直接启动了事务,但是需要再执行一条commit来提交;

因此建议设置set autocommit=1,此时需要用begin来开启事务,如果觉得多了一次交互,比较麻烦的话,也可以使用commit work and chain,表示提交当前事务,并且再启动一个新的事务,这样就只有一次begin了。

感谢阅读,有兴趣的小伙伴可以关注我的微信公众号DevOps探索之旅,大家一起学习进步

MySQL 什么是事务?的更多相关文章

  1. PHP mysql与mysqli事务详解

    官方对PHP连接到MySQL数据库服务器的三种主要的API简介如下: http://php.net/manual/zh/mysqli.overview.php PHP mysql与mysqli事务详解 ...

  2. 【MySQL】漫谈MySQL中的事务及其实现

    最近一直在做订单类的项目,使用了事务.我们的数据库选用的是MySQL,存储引擎选用innoDB,innoDB对事务有着良好的支持.这篇文章我们一起来扒一扒事务相关的知识. 为什么要有事务? 事务广泛的 ...

  3. MySQL数据库的事务管理

    当前在开发ERP系统,使用到的数据库为Mysql.下面介绍下如何开启事务,以及事务隔离的机制 : 1. 检查当前数据库使用的存储引擎. show engines; 2. 修改前my.ini中的文件如下 ...

  4. MySQL存储过程之事务管理

    原文链接:http://hideto.iteye.com/blog/195275 MySQL存储过程之事务管理 ACID:Atomic.Consistent.Isolated.Durable 存储程序 ...

  5. MySQL数据库分布式事务XA优缺点与改进方案

    1 MySQL 外部XA分析 1.1 作用分析 MySQL数据库外部XA可以用在分布式数据库代理层,实现对MySQL数据库的分布式事务支持,例如开源的代理工具:ameoba[4],网易的DDB,淘宝的 ...

  6. 漫谈MySql中的事务

    最近一直在做订单类的项目,使用了事务.我们的数据库选用的是MySql,存储引擎选用innoDB,innoDB对事务有着良好的支持.这篇文章我们一起来扒一扒事务相关的知识. 为什么要有事务? 事务广泛的 ...

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

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

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

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

  9. MySql中的事务嵌套

    1.Mysql中的事务必须是InnoDB.Berkeley DB引擎,myisam不支持. 2.Mysql是不支持嵌套事务的,开启了一个事务的情况下,再开启一个事务,会隐式的提交上一个事务. 3.My ...

  10. MySQL中Procedure事务编写基础笔记

    原文:MySQL中Procedure事务编写基础笔记 目录: 一.PROCEDURE: 二.CREATE PROCEDURE基本语法: 三.PROCEDURE小进阶   3.1.基本的DECLARE语 ...

随机推荐

  1. 【javaScript】报getElementId()为Null的错误

    若JavaScript代码写在<head>块中,若是javaScript,写JavaScript代码写在里面 window.οnlοad=function(){ js代码内容 } 若是jq ...

  2. SpringCloud学习之搭建eureka集群,手把手教学,新手教程

    一.为什么需要集群 上一篇文章讲解了如何搭建单个节点的eureka,这篇讲解如何搭建eureka集群,这里的集群还是本地不同的端口执行三个eureka,因为条件不要允许,没有三台电脑,所以大家将就一下 ...

  3. http1.0、http1.x、http 2和https梳理

    http1.0.http1.x.http 2和https梳理 Http1.x 线程阻塞,在同一时间,同一域名的请求有一定数量限制,超过限制数目的请求会被阻塞 http1.0 缺陷:浏览器与服务器只保持 ...

  4. java实现字符串翻转

    public class StringReverse { /*一共写了三个函数func1 func2 func3 * 时间: 2019年9月12日9:00 * func1用的反向输出到一个新的字符串中 ...

  5. x01.auto_input: 自动输入

    单位经常要把 excel 表的数据录入系统中,能够自动录入该多好. 花了几天时间,学习了一下 pandas 操作 excel 数据,利用 pyautogui 完成了一个自动录入的小测试,希望对有此需求 ...

  6. 多线程之CountDownLatch的用法及原理笔记

    前言-CountDownLatch是什么? CountDownLatch是具有synchronized机制的一个工具,目的是让一个或者多个线程等待,直到其他线程的一系列操作完成. CountDownL ...

  7. Flutter 入门 --- 内部分享

    八月部门给分配的分享任务,由于项目太赶,推迟一个月. 选 Flutter 这个主题,是因为现在它慢慢流行起来了,而我却不了解,故而借此契机,上手试试. 简介 Flutter 是 Google 推出的跨 ...

  8. ROS机器人之话题(一)

     将消息发布到话题上 首先建立一个basic包(名称自己定)其命令为: 1.创建功能包,应用catkin_create_pkg命令     cd  ~/catkin_ws/src #切换到代码空间,也 ...

  9. javase第一章(了解java)

    ------------恢复内容开始------------ java介绍 java这门语言,如果你是一名IT从业者,那么就一定是会有所耳闻的,毕竟,这是编程史上其商业化最成功的一门语言,当然, 编程 ...

  10. tmobst6

    1.(单选题)Oracle数据库中,在SQL语句中连接字符串的方法是:(). A)CAT B)CONCAT C)JOIN D)UNION 2.(单选题)在数据库中,有一个名为seq的序列对象,以下语句 ...