【数据库基础干货】数据库事务

本文详细介绍了数据库事务的ACID特性,包括原子性、一致性、隔离性和持久性,并探讨了不同隔离级别的应用场景。重点讲解了MySQL中InnoDB引擎的MVCC机制,如何解决并发事务中的读写冲突,以及Locks类型如RecordLocks、GapLocks和Next-KeyLocks的作用。同时,提到了undolog和redolog在事务恢复中的角色。
摘要由CSDN通过智能技术生成

数据库事务

A原子性(Atomicity)

一个事务里包含5条SQL语句,要么全部执行成功,要么全部执行失败,如果执行一半失败了需要回滚
在操作任何数据之前,首先将数据备份到undolog(回滚日志) 然后进行数据修改,如果出现错误或用户回滚,利用undolog中备份恢复到事务开始之前的状态
⚠️如果执行insert操作,undolog中相对应增加一条delete语句,同理update 2-5,undolog增加5-2

C一致性(Consistency)

原子性、隔离性、持久性是为了保证一致性

I隔离性(Isolation)

并发事务执行时互不干扰,等价于这些事务串行顺序跑,
常见的隔离级别为:读未提交、读已提交、可重复度、串行化

  • 读未提交 无法解决脏读
  • 读已提交 可以解决脏读(Oracle 默认级别)
  • 可重复读 可以解决不可重复读**(更新)** (MySQL默认事务隔离级别,但可以解决幻读)
  • 可串行化 可以解决幻读问题**(官方解释:事务T1读取一组满足某些<搜索条件>的数据。事务T2创建了(插入)满足T1的<搜索条件>的数据并提交。如果T1用相同的<搜索条件>再次读取,得到一组不同于第一次读取的数据)**

D持久性(Durability)

事务一旦提交,对数据库的更新就是持久的,由内存+redolog来保证,mysql修改数据同时在内存和redolog记录这次操作,事务提交的时候通过redolog刷盘,宕机的时候可以从redolog恢复。

持久化存储

  • 尽快落盘,在写入核心数据结构之前,需要先写事务log,MySQL InnoDB称为redolog,即使数据库挂了,重启恢复数据时,必须先从log中redo,为了吞吐量,可以配置每隔一段时间/事务刷盘,意味着系统挂掉会丢失一部分事务。
  • 复制,对数据尽可能多的副本,failover应对机器挂掉的风险

为了防止事务两次读取的数据不一致(包括不可重复读和幻读)
采用MVCC处理读写冲突的情况,不同的事务在并发过程中,SELECT操作可以在不加锁而是通过MVCC的机制读取指定版本的历史记录,MVCC是MySQL InnoDB实现隔离级别的一种方式
常见并发事务过程存在的问题:脏读、不可重复度、幻读,实现隔离机制方法一般有两种

  1. 加读写锁
  2. MVCC,指的是多个版本快照,快照存储在undo日志中,该日志通过回滚指针 ROLL_PTR 把一个数据行的所有快照连接起来

MySQL中MVCC的实现

  • MySQL中InnoDB引擎默认支持MVCC,读写早期只有读读阻塞,读写、写读、写写都要阻塞,引入MVCC后只有写写阻塞
  • 应对高并发事务,MVCC比单纯的加行锁更有效,开销更小,普通的SELECT读对数据库不会对数据加锁,提高了数据库并发处理能力
  • MVCC在 读已提交 和 可重复读隔离级别下起作用:而未提交读隔离级别总是读取最新的数据行,要求很低,无需使用 MVCC。可串行化隔离级别需要对所有读取的行都加锁,单纯使用 MVCC 无法实现,在可重复读隔离级别下,使用 MVCC + Next-Key Locks 可以解决幻读问题。(MySQL隔离级别为幻读的特殊处理)
  • MVCC 既可以基于乐观锁又可以基于悲观锁实现

InnoDB每一行数据都有两个隐藏列:ID为隐含ID,DATA_TRX_ID记录更新这条行记录的事务ID、DATA_ROLL_PTR指向回滚段的指针,通过这个指针找到之前版本ID,就可以找到之前行数据

undolog与redolog

  • undolog 有时事务需要撤销,这时需要进行undo,当有错误或回滚时,回滚日志记录着事务所执行的修改操作,在回滚时反向执行这些修改操作即可恢复之前版本。
  • redolog(前滚日志) 方便通过其进行重做,在事务执行时,往InnoDB日志缓存(log buffer)中插入redolog;事务提交时,将日志缓冲写入磁盘。系统发生奔溃可以用重做日志(Redo Log)进行恢复,从而实现持久性。类比赊账本,先写进redolog,然后循环写方式持久化

举个栗子:
假设有A、B两个数据,值分别为1、2,开启事务分别对其进行修改A → 3,B → 4,在提交,过程如下:
事务开始
记录A=3到redo log
修改A=3
记录A=1到undo log
记录B=4到redo log
修改B=4
记录B=2到undo log
将redo log写入磁盘
事务提交

几种Locks

  • Record Locks:锁定一个记录上的索引,而不是记录本身。如果表没有设置索引,InnoDB 会自动在主键上创建隐藏的聚簇索引,因此 Record Locks 依然可以使用。
  • Gap Locks:锁定索引之间的间隙,但是不包含索引本身,当执行以下操作时,其他事物不能向库表中插入15
SELECT c FROM t WHERE c BETWEEN 10 and 20 FOR UPDATE;
  • Next-Key Locks间隙锁:是 Record Locks 和 Gap Locks 的结合,不仅锁定一个记录上的索引,也锁定索引之间的间隙。它锁定一个前开后闭区间
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值