• MySQL高级篇——事务


    一、简介

    1. 什么是事务

    事务是由一个或多个sql语句组成一个最小的不可再分的工作单元。里面的内容要么都执行成功,要么都不成功。

    2. 事务的ACID特性

    • 原子性(atomicity)
      事务是一个不可分割的工作单元,要么全部提交,要么全部失败回滚。
    • 一致性(consistency)
      一致性指事务执行前后,数据从一个合法性状态变换到另一个合法性状态。例如要满足存在的约束,满足数据的一致性等、
    • 隔离性(isolation)
      指一个事务的执行不能被其他事务干扰。
    • 持久性(durability)
      一个事务一旦提交成功,它对数据库中数据的改变将是永久性的,接下来的其他操作或故障不应对其有任何影响。

    3. 存储引擎支持情况

    show engines 命令可以查看mysql存储引擎支持事务的情况。
    在这里插入图片描述
    在mysql中,只有innodb是支持事务的。


    二、开启事务

    1. 显式事务

    START TRANSACTION或BEGIN能显式的开启一个事务。

    BEGIN;
    # 或者
    START TRANSACTION
    • 1
    • 2
    • 3

    START TRANSACTION相较于BEGIN可以在后边跟随几个修饰符。

    • READ ONLY : 表示当前事务是一个只读事务
    • READ WRITE : 当前事务是一个读写事务
    • WITH CONSISTENT SNAPSHOT 启动一致性读(在开启事务的时候就生成Readview)

    事务的相关操作如下:

    COMMIT;
    ROLLBACK;
    ROLLBACK TO [SAVEPOINT];
    SAVEPOINT 保存点名称;
    RELEASE SAVEPOINT 保存点名称; #删除保存点
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2. 隐式事务

    如果不显式使用START TRANSACTION或BEGIN开启一个事务,那么每一条语句是一个独立的事务,这种特性叫做事务的自动提交。
    如果想关闭自动提交,有两种方法:

    • 显式使用START TRANSACTION或BEGIN
    • 把系统变量autocommit的值设置为off

    注意事项——隐式提交

    • 数据定义语言。当使用create、alter、drop等语句去修改数据库对象时,就会隐式提交前边语句所属的事务。
    • 当我们在一个事务还未提交或回滚时又使用START TRANSACTION或BEGIN开启一个事务时,会提交上一个事务。

    三、事务的隔离级别

    1. 介绍

    SQL在并发事务执行过程中可能存在以下问题:

    脏写、脏读、不可重复读、幻读
    
    • 1

    mysql提供四种隔离级别,用来解决并发问题:

    • READ UNCOMMITTED : 读未提交,在该隔离级别下,所有事务都可以看到其他事务未提交的数据。不能避免脏读、不可重复读、幻读。
    • READ COMMITTED : 读已提交,一个事务只能看到已经提交的事务。可以避免脏读,不能避免不可重复读、幻读。
    • REPEATABLE READ : 可重复读,事务A在读到记录后,其他事务对该记录修改后,A事务读到的还是原来的内容。可以避免脏读、不可重复读,不能避免幻读。这是mysql默认的隔离级别。
    • SERIALIZABLE : 可串行化,所有事务串行执行。

    2. 设置

    show variables like 'tx_isolation'; # 查看隔离级别,mysql5.7.20之前
    show variables like 'transaction_isolation' # 查看隔离级别,mysql5.7.20之后
    select @@transaction_isolation
    
    SET [GLOBAL|SESSION] TRANSACTION_ISOLATION = '隔离级别'
    
    • 1
    • 2
    • 3
    • 4
    • 5

    四、undo日志

    undo log是事务原子性的保证,在事务更新数据时需要先写入undo log。

    1 作用

    • 回滚数据

    用户对undo日志可能有误解:undo用于将数据库物理地恢复到执行语句或事务之前的样子。但事实并非如此。undo是逻辑日志,因此只是将数据库逻辑地恢复到原来的样子。所有修改都被逻辑地取消了,但是数据结构和页本身在回滚之后可能大不相同。
    这是因为在多用户并发系统中,可能会有数十、数百甚至数千个并发事务。数据库的主要任务就是协调对数据记录的并发访问。比如,一个事务在修改当前一个页中某几条记录,同时还有别的事务在对同一个页中另几条记录进行修改。因此,不能将一个页回滚到事务开始的样子,因为这样会影响其他事务正在进行的工作。

    MVCC

    undo的另一个作用是MVCC,即在InnoDB存储引擎中MNCc的实现是通过undo来完成。当用户读取一行记录时,若该记录已经被其他事务占用,当前事务可以通过undo读取之前的行版本信息,以此实现非锁定读取。

    2 结构

    InnoDB对undo log的管理采用段的方式,也就是回滚段(rollback segment),每个回滚段记录类1024个undo log segment

    innodb_undo_directory : 设置文件所在路径。
    innodb_undo_tablespaces : 设置文件数量.
    
    • 1
    • 2

    undo log类型分为:

    • insert undo log

    因为insert操作的记录,只对事务本身可见,对其他事务不可见。故该undo log可以在事务提交后直接删除,不需要进行purge操作

    • update undo log

    该undo log可能需要提供MVCC机制,因此不能在事务提交时就进行删除。提交时放入undo log链表,等待purge线程进行最后的删除

    3 工作流程

    在这里插入图片描述


    五、redo日志

    redo log称为重做日志,提供再写入操作,恢复提交事务修改页操作,用来保证事务的持久性。
    redo log记录的是物理级别上页的修改操作。

    1. WAL

    InnoDB的事务存储引擎,其通过Force Log at Commit机制实现事务的持久性,即当事务提交时,先将redo log buffer写入到redo log file进行持久化,待事务的commit操作完成后才算完成。这种做法也被称为Write-Ahead Log(预先日志持久化),在持久化一个数据页之前,先将内存中相应的日志持久化。

    2. 刷盘策略

    通过调整innodb_flush_log_at_trx_commit,支持不同的刷盘策略:

    • 0 : 表示每次事务提交时不进行刷盘操作,由系统后台线程每隔1s进行一次同步。
    • 1 : 默认为1,表示每次事务提交时都将进行同步,刷盘操作
    • 2 : 表示每次事务提交时都只写到oage cache,不进行同步,由os自己决定什么时候同步到磁盘。
  • 相关阅读:
    车牌识别平台开源(支持蓝牌、绿牌,准确率高达96%)
    python随手小练4
    MacOS - ToDesk 无法远程操控鼠标键盘解决方案
    Git --》Git常用命令使用
    Day45-9大内置对象、JSP标签、JSTL标签、EL表达式、JavaBean
    50 jhat 中 java.lang.String 的实例占用空间为什么是 28 bytes ?
    2023-08-23 AndroidR 自主研究出来的三手指下滑截屏功能
    [MRCTF2020]Ezpop-1|php序列化
    公交实时位置查询APP
    深度学习(part3)--深度学习框架tensorflow
  • 原文地址:https://blog.csdn.net/qq_51114283/article/details/126725565