• 【数据库】从事务到锁机制


    本系列包含:


    1.什么是事务?

    一组原子性的 SQL 语句,或者说一个独立的工作单元。(由一个有限的数据库操作序列构成,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。)

    • 事务拥有 ACID(原子性、一致性、隔离性、持久性)四个特性。
    • 事务通过 日志文件(undo log 和 redo log)实现可靠性。
    • 事务通过 隔离级别 实现并发处理。
    • 实现事务功能的三个技术:日志文件(redo log 和 undo log)、锁技术、MVCC。

    2.redo log 和 undo log

    • redo log 是用来恢复数据的,用于保障已提交事务的持久化特性。
    • undo log 是用来回滚数据的,用于保障未提交事务的原子性。

    3.读写锁实现了事务的隔离性

    • shared lock:共享锁、读锁。
    • exclusive lock:排他锁,写锁。

    4.MVCC

    MVCC(MultiVersion Concurrency Control),中文叫 多版本并发控制,它是通过读取历史版本的数据,来降低并发事务冲突,从而提高并发性能的一种机制。它的实现依赖于 隐式字段、undo日志、快照读&当前读、Read View。

    • InnoDB 的 MVCC ,是通过在每行记录的后面保存两个隐藏的列来实现的。这两个列, 一个保存了行的创建时间,一个保存了行的过期时间, 当然存储的并不是实际的时间值,而是系统版本号。
    • MVCC 在 MySQL 中的实现依赖的是 undo log 与 Read View。undo log 中记录某行数据的多个版本的数据。Read View 用来判断当前版本数据的可见性。
    • 快照读:读取的是记录数据的可见版本(有旧的版本),不加锁,普通的 select 语句都是快照读。
    • 当前读:读取的是记录数据的最新版本,显示加锁的都是当前读。
    • Read View 就是事务执行快照读时,产生的读视图。事务执行快照读时,会生成数据库系统当前的一个快照,记录当前系统中还有哪些活跃的读写事务,把它们放到一个列表里。Read View主要是用来做可见性判断的,即判断当前事务可见哪个版本的数据 ~

    5.实现事务采取了哪些技术以及思想?

    • 原子性:使用 undo log,从而达到回滚。
    • 持久性:使用 redo log,从而达到故障后恢复。
    • 隔离性:使用锁以及 MVCC,运用的优化思想有读写分离,读读并行,读写并行。
    • 一致性:通过回滚,以及恢复,和在并发环境下的隔离做到一致性。

    6.并发事务存在哪些问题?

    • 脏读:事务 A、B 交替执行,事务 A 被事务 B 干扰到了,因为事务 A 读取到事务 B 未提交的数据。
    • 不可重复读:在事务 A 范围内,两个相同的查询,读取同一条记录,却返回了不同的数据。
    • 幻读:事务 A 查询一个范围的结果集,另一个并发事务 B 往这个范围中 插入 / 删除 了数据,并静悄悄地提交,然后事务 A 再次查询相同的范围,两次读取得到的结果集不一样了。

    7.既然并发事务存在脏读、不可重复、幻读等问题,InnoDB 实现了哪几种事务的隔离级别应对呢?

    • 读未提交(Read Uncommitted,RU):在读未提交隔离级别下,一个事务会读到其他事务未提交的数据的,即存在脏读问题。事务 B 都还没 commit 到数据库呢,事务 A 就读到了,感觉都乱套了。实际上,读未提交是隔离级别最低的一种。
    • 读已提交(Read Committed,RC):为了避免脏读,数据库有了比读未提交更高的隔离级别,即读已提交。但是,隔离级别设置为读已提交的时候,还会存在不可重复读的并发问题。
    • 可重复读(Repeatable Read,RR):解决了不可重复读的问题,但没有完全解决存在的幻读问题。
    • 串行化(Serializable):当数据库隔离级别设置为 serializable 的时候,事务 B 对表的写操作,在等事务 A 的读操作。其实,这是隔离级别中最严格的,读写都不允许并发。它保证了最好的安全性,性能却是个问题。

    8.MySQL 是怎样实现上述四种不同的隔离级别的呢?

    MySQL 使用不同的 锁策略 / MVCC 来实现四种不同的隔离级别。RC、RR 的实现原理跟 MVCC 有关,RU 和 Serializable 的实现原理跟锁有关。

    • 读未提交,采取的是读不加锁原理。事务读不加锁,不阻塞其他事务的读和写。事务写阻塞其他事务写,但不阻塞其他事务读;
    • 串行化中,读加共享锁,写加排他锁,读写互斥。如果有未提交的事务正在修改某些行,所有 select 这些行的语句都会阻塞。
    • RC 跟 RR 隔离级别,最大的区别就是:RC 每次读取数据前都生成一个 ReadView,而 RR 只在第一次读取数据时生成一个 ReadView。

    参考资料

    【1】一文彻底读懂 MySQL 事务的四大隔离级别
    【2】图解 mysql 事务实现原理

  • 相关阅读:
    Asp .Net Core 系列:基于 Castle DynamicProxy + Autofac 实践 AOP 以及实现事务、用户填充功能
    【POJ No. 1182】 食物链
    Spring Boot 实现万能文件在线预览-开源学习一
    AQS原理
    【需水预测】区域需水量预测方法-定额法
    MAUI候选版本3发布啦
    【进阶】Spring中的注解与反射
    怎么使用Java运算符和JShell脚本工具
    ABAP ALSM_EXCEL_TO_INTERNAL_TABLE 导入Excel的几个问题
    加密,各种加密,耙梳加密算法(Encryption)种类以及开发场景中的运用(Python3.10)
  • 原文地址:https://blog.csdn.net/be_racle/article/details/126561247