事务是数据库管理系统(DBMS)执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。

                                                                                                                                                      ------维基百科的定义

MySQL中 InnoDB支持事务,这个也是它成为默认的存储引擎的一个重要原因,对于需要事务支持的业务场景有更好的适用性

数据库事务

事务的四大特性

事务的四大特性:ACID

1.原子性,Atomicity  原子(atom)是化学反应中不可再分的基本微粒,顾名思义,这也就说明对数据库的一系列的操作,是不可分割的整体,要么都是成功,要么都是失败,不可能出现部分成功或者部分失败的情况。
原子性,在InnoDB里面是通过undo log来实现的,它记录了数据修改之前的值(逻辑日志),一旦发生异常,就可以用undo log来实现回滚操作。

2.一致性,consistent  所说的是数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。比如主键必须是唯一的,字段长度需要符合要求。除了数据库自身的完整性约束,还有一个是用户自定义的完整性。
以转账场景来举例,A账户余额减少1000,B账户余额只增加了500,这个时候就没有满足一致性。
用户自定义的完整性通常要在代码中控制。

3.隔离性,Isolation   在数据库里面会有很多的事务同时去操作同一张表或者同一行数据,必然会产生一些并发或者干扰的操作。所谓的隔离性,就是多个事务,对表或者行的并发操作,应该是互相不干扰的。这样来可以保证业务数据的一致性。

4.持久性,Durable  所谓持久性就是或我们对数据库的任意的操作,增删改,只要事务提交成功,那么结果就是永久性的,不会因为我们系统宕机或者重启了数据库的服务器,又恢复到原来的状态了。
数据库崩溃恢复(crash-safe)是通过redo log和double write双写缓冲来实现的,我们操作数据的时候,会先将其写到内存的buffer pool里面,同时记录redo log,如果在数据刷盘之前出现异常,在重启后就可以读取redo log的内容,写入到磁盘,保证数据的持久性。当然,恢复成功的前提是数据页本身没有被破坏,是完整的,这个通过双写缓冲(double write)保证。

事务的开启方式

事务开启分为两种方式,手动开启提交和自动开启提交。
我们平时写一个SQL:update user set  name='chenpp' where id=1;这里就已经自动开启了一个事务,并且提交了。
InnoDB里面有一个autocommit的参数(分成两个级别, session级别和global级别),可以通过set session autocommit = on/off; -- 设定事务是否自动开启 。平时是默认开启的

手动开启事务也有两种方式,一种是使用begin;另一种是用start transaction。
结束事务也有两种方式,提交一个事务commit;或者回滚 rollback
还有一种情况,客户端的连接断开的时候,事务也会结束。

事务并发会造成的问题

当多个事务并发操作数据库的表或者行的时候,如果没有事务的Isolation隔离性,会带来哪些问题呢?

事务并发的三大问题:脏读,不可重复读,幻读

脏读


这种读取到其他事务未提交的数据的情况,我们把它叫做脏读。

不可重复读

这种一个事务读取到了其他事务已提交的数据导致前后两次读取数据不一致的情况,我们把它叫做不可重复读。

幻读


由于其他事务插入数据造成一个事务前后两次读取数据数据不一致,这种情况我们把它叫做幻读。
不可重复读和幻读的区别在于 不可重复读是由于修改或者删除导致,幻读是由于插入导致的

无论是脏读,还是不可重复读,幻读,都是数据库的读一致性的问题,都是在一个事务里面前后两次读取出现了不一致的情况。
读一致性的问题,必须要由数据库提供一定的事务隔离机制来解决

SQL92 标准

http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt

Possible代表在这个隔离级别下,这个问题有可能发生

第一个隔离级别:Read Uncommitted(未提交读),一个事务可以读取到其他事务未提交的数据,可能出现脏读,它没有解决任何的问题。
第二个隔离级别:Read Committed(已提交读),一个事务只能读取到其他事务已提交的数据,不能读取到其他事务未提交的数据,它解决了脏读的问题,但是可能会出现不可重复读的问题。
第三个隔离级别:Repeatable Read (可重复读),它解决了不可重复读的问题,就是说在同一个事务里面多次执行同样的SQ其返回的数据结果是一样的,但是在这个级别下,没有解决幻读的问题。
第四个隔离级别:Serializable(串行化),在这个隔离级别里面,所有的事务都是串行执行的,也就不存在事务的并发操作问题了,所以它解决了所有的问题。

MySQL InnoDB 对隔离级别的支持

在MySQL InnoDB里面,不需要使用串行化的隔离级别去解决所有问题。
看下MySQL InnoDB里面对数据库事务隔离级别的支持程度是什么样的

注意一下,InnoDB在Repeatable Read(RR)的级别就解决了幻读的问题。这个也是InnoDB默认使用RR作为事务隔离级别的原因,既保证了数据的一致性,又支持较高的并发度。

解决读一致性的实现方案

LBCC

要保证前后两次读取数据一致,那么直接在读取数据的时候,锁定读取的数据,不允许其他的事务修改就行了。这种方案我们叫做基于锁的并发控制Lock Based Concurrency Control(LBCC)
如果仅仅是基于锁来实现事务隔离,一个事务读取的时候是不允许其他事务修改的,那就意味着不支持并发的读写操作,这样会极大地影响操作数据的效率,毕竟我们的大多数应用都是读多写少的

MVCC

另一种解决方就是使用快照,就是在修改数据的时候给它建立一个备份或者快照,后面在本事务里再次执行的时候只要读取这个快照就行了。这种方案我们叫做多版本的并发控制 Multi Version Concurrency Control(MVCC)。MVCC使得InnoDB的事务隔离级别下执行一致性读操作有了保证。简单说就是为了查询一些正在被另一个事务更新的行,并且可以看到它们被更新之前的值

MVCC的核心思想是: 我可以查到在我这个事务开始之前已经存在的数据,即使它在后面被修改或者删除了。而在我这个事务开始之后新增的数据,我是查不到的。
为了实现MVCC , InnoDB为每行记录都实现了两个隐藏字段:
DB_TRX_ID,6字节:插入或更新该行的最后一个事务的事务ID,事务编号是自动递增的(可以理解为类似创建版本号)
DB_ROLL_PTR,7字节:回滚指针(可以理解为删除版本号,当数据被删除或记录为旧数据的时候,当前的事务ID)。

看下MVCC在不同场景下的使用:

1)新增数据

事务1插入了2条数据并提交,事务2此时查询了当前表,可以看到2条记录,此时事务3又插入了一条新的记录,之后事务2又查询了一次

MVCC的查找规则:只能查找创建时间小于等于当前事务ID的数据,和删除时间大于当前事务ID的行(或未删除)。

也就是说不能查到在 本次事务开始之后插入的数据,Bob的创建事务ID大于2,所以还是只能查到两条记录。

2)删除数据

事务3删除了id=1的数据,事务2此时又查询了当前表

Bob的创建版本大于2不满足,chenpp的删除版本大于2仍旧满足,所以查询到的还是id=1和id=2两条记录

3)修改数据

此时事务5执行了一个更新SQL update user set name='Mon' where id=2; ,之后事务2又查询了一次

Mon,Bob创建版本大于2不满足,CoCo删除版本大于2仍旧满足,所以还是2条记录

在InnoDB中,MVCC是通过Undo log实现的。

快照读和当前读

  • 快照读:读取的是快照版本,也就是历史版本
  • 当前读:读取的是最新版版

在InnoDB中,MVCC和锁是协同使用的:在RR隔离级别下,普通的select使用快照读(snapshot read),底层使用MVCC来实现。
加锁的 select(select ... in share mode / select ... for update)以及更新操作update, delete 等语句使用当前读(current read),底层基于锁实现(LBCC)。

MySQL(五)MySQL事务相关推荐

  1. MySQL的基本学习(五)——事务、DCL和SQL基图

    MySQL的基本学习(五)--事务.DCL和SQL基图 前言 前面写了一篇比较短的文章简单记录了一下多表查询的利用示例,这篇文章我们来继续学习MySQL数据库,我们这篇主要是学习事务的概念还有SQL语 ...

  2. mysql第五章事务_mysql 第五章 备份恢复

    mysql 第五章 备份恢复 一.备份策略***** 1.每周一次全备,每天一次增量备 2.每天检查备份是否成功 3.每季度进行备份恢复演练 4.设置 -master-data=2 (记录备份的GTI ...

  3. MySQL(五) 事务,索引,用户管理和备份

    事务 要么都成功,要么都失败(类似try代码块?) 一一一一一一一一一一一一一 A给B转账 - SQL1 A账面转出 - SQL2 B账面收到 一一一一一一一一一一一一一 若SQL2执行时或执行前出现 ...

  4. mysql如何查看事务日记_MySQL中的几种日志了解

    前言 MySQL中有以下日志文件,分别是: 1:重做日志(redo log) 2:回滚日志(undo log) 3:二进制日志(binlog) 4:错误日志(errorlog) 5:慢查询日志(slo ...

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

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

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

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

  7. mysql四种事务隔离级别

    mysql事务并发问题 ACID什么的就不啰嗦了.mysql多个事务并发的时候,可能会出现如下问题: 1. 更新丢失 即两个事务同时更新某一条数据,后执行的更新操作会覆盖先执行的更新操作,导致先执行的 ...

  8. 事务复制提示初始快照不可用_「MySQL」数据库事务深入分析

    推荐阅读:吊打面试官!MySQL灵魂100问,你能答出多少? 一.前言 只有InnoDB引擎支持事务,下边的内容均以InnoDB引擎为默认条件 二.常见的并发问题 1.脏读 一个事务读取了另一个事务未 ...

  9. mysql数据库执行事务日志_第十章 MySQL事务及其日志介绍

    一.数据库升级 #1.提出方案 1)升级的方法 2)升级的步骤 3)升级的时间 4)升级步骤可能会出现的问题 5)出现的问题怎么解决,解决时间 6)升级后出现的问题 #2.搭建新的数据库 #3.备份就 ...

最新文章

  1. 2017-2018-1 20155204 《信息安全系统设计基础》第十一周学习总结
  2. python学习笔记 day44 数据库三范式
  3. JavsScript--on与addEventListener的使用与两者的不同
  4. 存储 萤石云_同时用过小米米家智能猫眼(带屏)与萤石dp1s智能门铃之后的感受...
  5. mysql不能创建innodb类型表_MYSQL have_innodb DISABLED无法创建innodb类型的表
  6. 麻将游戏-协议实现 笔记
  7. 用vue实现简单实时汇率计算功能
  8. (4)HTML标签补充和HTML转义字符
  9. arm-linux-gcc 没有那个文件或目录
  10. NSString copy or not (strong)?
  11. 转载:java生成eps
  12. Oracle-随笔笔记
  13. 已知三角形顶点坐标,求其外接圆的公式
  14. c free 语言随机抽签,javascript随机抽签程序详解
  15. python画红蓝相间同心圆_Python 实现的、带GUI界面的词云生成器
  16. matlab里impz指令格式,华北电力大学Matla实验指导书.doc
  17. 与“雾霾”相关的英语表达
  18. 大白菜U盘PE重装系统
  19. 一款英国折叠车如何在中国城市流行?
  20. php中如何过滤关键字,PHP - 过滤关键字

热门文章

  1. spring事务环境搭建
  2. JavaScript中替换字符串中的所有小数点
  3. webflux系列--基础
  4. linux音频框架分析,Alsa音频子系统Codec---al5623.c内核代码框架分析
  5. python请输入_不断提示用户输入Python
  6. FortiGate设置E-mail告警
  7. 点击按钮修改背景颜色及节点操作隔行变色案例
  8. 修改Tomcat7的/webapps/ROOT发布路径
  9. 浅谈EntityFramework框架的使用
  10. 杭电2502--月之数