• MySQL事务


    事务特性

    • 原子性(atomicity)
    • 一致性(consistency)
    • 隔离性(isolation)
    • 持久性(durability)

    事务隔离级别

    READE UNCOMMITTED(未提交度)

    允许脏读,也就是可能读取到其他会话中未提交事务修改的数据

    READ COMMITTED(提交读)

    只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)

    REPEATABLE READE(可重复读)

    可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读

    SERIALIZABLE(可串行化)

    完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

    隔离级别 脏读 不可重复读 幻读
    未提交读 可能 可能 可能
    已提交读 不可能 可能 可能
    可重复读 不可能 不可能 可能
    可串行化 不可能 不可能 不可能

    事务隔离级别名词解释

    什么是脏读

    脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

    什么是不可重复读

    指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

    什么是幻读

    指的是当某个事务在读取某个范围内的记录时, 另外一个事务又在该范围内插入了新的记录,当之前的事务再次 读取该范围的记录时,会产生幻行(Phantom Row)。

    MySQL利用间隙锁解决了幻读

    更改Mysql事务隔离级别

    临时生效

    SET @@session.transaction_isolation = 'READ-UNCOMMITTED';
    SET session transaction isolation level read uncommitted;
    

    永久性生效

    打开Mysql配置文件增加如下:

    transaction-isolation = READ-COMMITTED
    

    查看Mysql事务隔离级别

    # 全局配置
    SELECT @@global.tx_isolation;
    
    # 当前会话配置
    select @@session.tx_isolation;
    

    redo log 和 undo log

    提到MySQL事务不得不说下,重做日志和回滚日志。

    重做日志

    基本概念

    重做日志用来实现事务的持久性,即事务 ACID 中的 D。其由两部分组成:

    • 内存中的重做日志缓冲(redo log buffer)
    • 磁盘重做日志文件(redo log file)

    核心原理:当提交一个事物,InnoDB存储引擎,必须完成 redo log 数据持久化,待事务 COMMIT 操作完成才算完成。另外重做日志还是满足幂等性。

    重做日志块

    重做日志是以512字节进行存储的。这意味着重做日志缓存、重做日志文件都是以块(block)的方式进行保存的,称之为重做日志块(redo log block),每块的大小为512字节。

    若一个页中产生的重做日志数量大于512字节,那么需要分割为多个重做日志块进行存储。

    重做日志块组成结构

    重做日志相关参数

    参数名 备注 默认值
    innodb_log_file_size 重做日志文件大小 48M
    innodb_log_files_in_group 指定重做日志文件组中文件的数量 2
    innodb_log_group_home_dir 指定日志文件组所在的路径 ./
    innodb_flush_log_at_trx_commit 控制ACID日志刷新到磁盘策略 1

    回滚日志

    基本概念

    当提交一个事务时,Innodb自动把修改前的数据备份到 redo log 中,当提交失败或者系统异常奔溃可通过 redo log 实现回滚。

    注意:redo log 是逻辑回滚。

    快照读

    MySQL利用 redo log 实现了非锁定读

    事务A 修改 ID = 1 数据,此时MySQL会对该资源进行锁定(独占锁)
    
    事务B 查询 ID = 1 数据,此时就属于快照度。因为事务A 原始数据已经被备份到 redo log 中。
    

    undo log 格式类别

    insert undo log

    insert undo log是在insert操作中产生的undo log。因为insert操作的记录,只对事务本身可见,对其他事务不可见(这是事务隔离性要求),故该undo log可以在事务提交后直接删除。不需要进行purge操作。

    update undo log

    update undo log记录的是对 deleteupdate 操作产生的undo log。因MVCC机制存在,所有不能在事务提交时就进行删除。提交时放入 undo log 链表,等待purge线程进行最后的删除。

    为什么不能在事务提交后立马删除?

    ID 事务A 事务B
    1 begin begin
    2 - 删除ID=1数据
    3 - commit
    4 查询ID=1数据
    5 commit

    结论:如果事务B立马执行删除,这将导致事务A查不到任何数据,破坏了ACID特性。

  • 相关阅读:
    HDU 2546:饭卡(01背包)
    HPU 第三次积分赛:阶乘之和(水题)
    拓扑排序练习题
    HDU 2647:Reward(拓扑排序+队列)
    HDU 3342:Legal or Not(拓扑排序)
    HDU 2094:产生冠军(拓扑排序)
    POJ 2585:Window Pains(拓扑排序)
    51Nod 1002:数塔取数问题(DP)
    cogs696 longest prefix
    poj3764 The xor-longest Path
  • 原文地址:https://www.cnblogs.com/zhanghuizong/p/12674960.html
Copyright © 2020-2023  润新知