mysql8.0事务学习

1、基本概念

事务(Transaction)是访问和更新数据库的程序执行单元;是一个最小的不可分割的工作单元,能保证一个业务的完整性;事务中可能包含一个或多个sql语句,这些语句要么都执行,要么都不执行。事务只和DML语句有关,或者说只有DML语句才有事务,如果业务逻辑不同,DML语句的个数也不同。在MySQL中,默认情况下事务是自动提交的。

DML(data manipulation language)数据操纵语言:就是我们最经常用到的 SELECT、UPDATE、INSERT、DELETE。 主要用来对数据库的数据进行一些操作。
DDL(data definition language)数据库定义语言:其实就是我们在创建表的时候用到的一些sql,比如说:CREATE、ALTER、DROP等。DDL主要是用在定义或改变表的结构,数据类型,表之间的链接和约束等初始化工作。
DCL(Data Control Language)数据库控制语言:是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。

2、 提交和回滚

提交和回滚针对的是dml语句,ddl语句会直接提交事务。典型的MySQL事务是如下操作的

start transaction;
…… #一条或多条sql语句
commit;

其中start transaction标识事务开始,commit提交事务,将执行结果写入到数据库。如果sql语句执行出现问题,会调用rollback,回滚所有已经执行成功的sql语句。当然,也可以在事务中直接使用rollback语句进行回滚。

自动提交:MySQL中默认采用的是自动提交(autocommit)模式,如果没有start transaction显式地开始一个事务,那么每个sql语句都会被当做一个事务执行提交操作。如下所示:

=

autocommit参数是针对连接的,在一个连接中修改了参数,不会对其他连接产生影响。
关闭autocommit:如果关闭了autocommit,则所有的sql语句都在一个事务中,直到执行了commit或rollback

3、ACID是衡量事务的四个特性

原子性(Atomicity):语句要么全执行,要么全不执行,是事务最核心的特性,事务本身就是以原子性来定义的;实现主要基于undo log,记录事务之前原始的数据,
一致性(Consistency):保证事务提交后不会因为宕机等原因导致数据丢失,即数据库的完整性约束没有被破坏 ;实现主要基于redo log,记录事务修改后数据。
隔离性(Isolation):保证事务和事务之间是相互分离,互不影响;InnoDB默认的隔离级别是RR(可重复读),RR的实现主要基于锁机制(包含next-key lock)、MVCC(包括数据的隐藏列、基于undo log的版本链、ReadView)
持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚,MySQL 事务的持久性主要基于redo log。

4、事务的并发问题

脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。
不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。
幻读:就好像发生了幻觉一样,比如:明明当前事务查询没有这条结果,理应可以在当前事务进行新增操作,但是却提示记录已存在不能插入相同主键记录,这就是幻读,或者修改明明是全表update,但是执行成功后再进行查询却发现还有一条记录没有更新成功,这也是幻读。
其中:
不可重复读的和幻读区别:不可重复读侧重于修改或删除,幻读侧重于新增。不可重复读是select同一个数据发现的到的结果跟刚才不一样。幻读是比不可重复读高一个级别的错误,读取同一条数据发现跟刚才是一样的,只有读取一堆数据发现忽然多了一个,或者少了一个,就像自己产生了幻觉!综上,不可重复读针对的是同一条数据,幻读针对的是一片数据。
解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。

5、锁

悲观锁:假定所有不同事务的处理一定会出现干扰,数据库中最严格的并发控制策略,如果一个事务正在对数据处理,那么在整个事务过程中,其他事务都无法对这个数据进行更新操作,直到该事务释放了这个锁。
乐观锁:假定所有不同事务的处理不一定会出现干扰,所以在大部分操作里不许加锁,但是既然是并发就有出现干扰的可能。在乐观锁中当提交更新请求之前,要先去检查读取这个数据之后该数据是否发生了变化,如果有变化,那么你此次的提交就要放弃,如果没有变化就可以提交。

6、事务隔离级别

事务隔离级别 名称 脏读 不可重复读 幻读
read-uncommitted 读未提交
read-committed 读已提交
repeatable-read 可重复读
serializable 串行化
 mysql默认隔离级别是“可重复读”,oracle默认隔离级别是“读已提交”。隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
可重复读 隔离级别表示, 你随便读,读多少次都没事,是好的一面。
MySQL InnoDB的mvcc机制解决不可重复读,并不保证完全避免幻读,需要应用使用加锁读来保证,mvcc属于乐观锁。
参考https://blog.csdn.net/qq_35590091/article/details/107734005

我的理解:1、事务的并发问题都是数据库读一致性的问题。2、回滚导致脏读,读已提交解决。3、不可重复读针对同一数据修改,锁行解决。4、幻读是查询和dml操作有间隙导致,锁表解决

7、事务提交过程

MySQL是通过WAL(Write-Ahead Logging)方式,来保证数据库事务的一致性和持久性

WAL是一种实现事务日志的标准方法,具体而言就是:
1、修改记录前,一定要先写日志;
2、事务提交过程中,一定要保证日志先落盘,才能算事务提交完成。
通过WAL方式,在保证事务特性的情况下,可以提高数据库的性能。

MySQL 本身不提供事务支持,而是开放了存储引擎接口,由具体的存储引擎来实现,具体来说支持 MySQL 事务的存储引擎就是 InnoDB。存储引擎实现事务的通用方式是基于 redo log 和 undo log。简单来说,redo log 记录事务修改后的数据, undo log 记录事务前的原始数据。在 MySQL 执行事务过程中如果因故障中断,可以通过 redo log 来重做事务或通过 undo log 来回滚,确保了数据的一致性。这些都是由事务性存储引擎来完成的,但 binlog 不在事务存储引擎范围内,而是由 MySQL Server 来记录的。

事务执行过程简化如下:

  1. 先记录 undo/redo log,确保日志刷到磁盘上持久存储。
  2. 更新数据记录,缓存操作并异步刷盘。
  3. 将事务日志持久化到 binlog。
  4. 提交事务,在 redo log 中写入commit记录。

这样的话,只要 binlog 没写成功,整个事务是需要回滚的,而 binlog 写成功后即使 MySQL Crash 了都可以恢复事务并完成提交。要做到这点,就需要把 binlog 和事务关联起来,而只有保证了 binlog 和事务数据的一致性,才能保证主从数据的一致性。所以 binlog 的写入过程不得不嵌入到纯粹的事务存储引擎执行过程中,并以内部分布式事务(xa 事务)的方式完成两阶段提交

MySQL8.0事务知识点的更多相关文章

  1. MySQL8.0 原子DDL

    Edit MySQL8.0 原子DDL 简介 MySQL8.0 开始支持原子 DDL(atomic DDL),数据字典的更新,存储引擎操作,写二进制日志结合成了一个事务.在没有原子DDL之前,DROP ...

  2. 深入解读MySQL8.0 新特性 :Crash Safe DDL

    前言 在MySQL8.0之前的版本中,由于架构的原因,mysql在server层使用统一的frm文件来存储表元数据信息,这个信息能够被不同的存储引擎识别.而实际上innodb本身也存储有元数据信息.这 ...

  3. MySQL8.0.19主从环境搭建(CentOS7)

    默认情况下,复制是异步的,从站不需要永久连接以接收来自主站的更新.根据配置,您可以复制数据库中的所有数据库,所选数据库甚至选定的表. MySQL中复制的优点包括: 横向扩展解决方案 - 在多个从站之间 ...

  4. Centos7安装MySQL8.0 - 操作手册

    MySQL 8 正式版 8.0.11 已发布,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能! 一.  Mysql8.0版本相比之前版本的一些特性 1) ...

  5. mysql8.0发布新特性

    2018年4月21日 14:36:42 https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-11.html#mysqld-8-0-11-b ...

  6. linux 中安装mysql8.0

    转载自:http://www.linuxidc.com/Linux/2016-11/137608.htm 可能有人会惊奇MySQL为何从5.x一下跳跃到了8.0.事实上,MySQL 5.x系列已经延续 ...

  7. mysql8.0的新特性

    https://www.cnblogs.com/kevingrace/p/10482469.html MySQL 8 正式版 8.0.11 已发布,官方表示 MySQL 8 要比 MySQL 5.7 ...

  8. CentOS7安装MySQL8.0小计

    之前讲配置文件和权限的时候有很多MySQL8的知识,有同志说安装不太一样,希望发个文,我这边简单演示一下 1.环境安装 下载MySQL提供的CentOS7的yum源 官方文档:<https:// ...

  9. MySQL-08 MySQL8.0新特性

    性能 MySQL 8.0 在一定的用户访问条件下,速度要比 MySQL 5.7 快 2 倍.MySQL 8.0 在以下方面带来了更好的性能:读/写工作负载.IO 密集型工作负载.以及高竞争(" ...

  10. MySQL8.0 redo日志系统优化

    背景 现在主流的数据库系统的故障恢复逻辑都是基于经典的ARIES协议,也就是基于undo日志+redo日志的来进行故障恢复.redo日志是物理日志,一般采用WAL(Write-Ahead-Loggin ...

随机推荐

  1. JDK中的动态代理

    江苏 无锡 缪小东 写到代理模式这章,不得不提到JDK中的动态代理,它是java语言自身对动态代理的支持,类似于JDK中在java.util包中提供Observable类和Observer接口提供对观 ...

  2. python多版本管理软件pyenv

    我们在平时的项目开发或者学习中,有可能使用不同的Python版本,大家都知道Python的版本非常多,如果我们把需要的不同版本的Python都下载到服务器上,管理起来会非常困难,多版本并存又容易互相干 ...

  3. UUID和雪花(Snowflake)算法该如何选择?

    UUID 和 Snowflake 都可以生成唯一标识,在分布式系统中可以说是必备利器,那么我们该如何对不同的场景进行不同算法的选择呢,UUID 简单无序十分适合生成 requestID, Snowfl ...

  4. Python之错误码设计

    在 web 项目中,我们经常使用自定义状态码来告知请求方请求结果以及请求状态:在 Python 中该如何设计自定义的状态码信息呢? 1)普通类+字典设计状态码 #!/usr/bin/python3 # ...

  5. vue 适配不同分辨率显示问题

    新建 js 文件 rem.js class DevicePixelRatio { constructor() { // this.flag = false; } // 获取系统类型 _getSyste ...

  6. 【Amadeus原创】SQL Server数据库备份、差异备份、日志备份脚本

    1,sp脚本 USE [master] GO /****** Object: StoredProcedure [dbo].[sp_BackupDatabase] Script Date: 2021/1 ...

  7. M1芯片pod问题

    M1芯片pod问题 换了M1芯片的mac后,在Xcode跑项目报pod错误,提示run pod install更新pod,但是去终端跑命令时又报错 然后在github上看到一个老哥的方法 https: ...

  8. k8s.HPA.使用自定义指标Pod自动扩容

    k8s.HPA.使用自定义指标Pod自动扩容 环境 env : kubernetes v1.22 metrics-server 0.6.1 prometheus v2.36.1 prometheus- ...

  9. Jackson基本使用教程

    目录 如何将一个Json序列化对象封装成为一个Pojo是实体类对象 如何进行序列化与反序列化 如何将数据进行绑定 如何进行泛型数据绑定 如何使用Jackson树模型(将复杂Json手动映射到类型) 使 ...

  10. 黑苹果(Hackintosh) - 问题,虚拟机中的黑苹果系统分辨率低,界面小

    问题截图 解决办法 先把 draw.iso 放进 VMware 的安装根目录 再设置 Mac OS 虚拟机系统的配置情况 如果实在不行 就使用 VM 的拉伸显示功能吧,就将就着用用