学无先后,达者为师

网站首页 编程语言 正文

InnoDB 事务

作者:Cloaks 更新时间: 2022-08-19 编程语言

文章目录

  • 概述
  • 隔离级别
  • 实现
    • redo log
      • 案例
      • undo log

概述

隔离级别

实现

redo log

redo log 叫做重做日志,是用来实现事务的持久性。
该日志有两部分组成:重做日志缓冲(redo log buffer)和重做日志文件(redo log)。
前者在内存中,后者在磁盘中。当事务提交之后会把所有修改信息存到该日志中,用于在刷新脏页到磁盘时,或者发生错误时,进行数据恢复使用。

案例

在银行转账操作中使用事务,从银行账户表中转出2000元到理财账户表中。

数据准备

select version();
8.0.30

create database if not exists db_test default character set utf8mb4 collate utf8mb4_0900_ai_ci;

use db_test;

create table if not exists tb_bank
(
    id      int primary key auto_increment,
    name    varchar(20) not null comment '账户名称',
    balance int         not null comment '账单资金'
) engine = innodb
  default charset = utf8mb4
  collate = utf8mb4_0900_ai_ci
    comment '银行账户表';

create table if not exists tb_finance
(
    id      int primary key auto_increment,
    name    varchar(20) not null comment '账户名称',
    account int         not null comment '账单资金'
) engine = innodb
  default charset = utf8mb4
  collate = utf8mb4_0900_ai_ci
    comment '理财账户表';

insert into tb_bank
values (null, 'Tom', 10000);
insert into tb_finance
values (null, 'Tom', 0);

数据验证

select * from tb_bank;
1,Tom,10000
select * from tb_finance;
1,Tom,0

执行事务操作

start transaction;

select balance from tb_bank where name = 'Tom';

-- 生成重做日志 balance = 8000
update tb_bank set balance = balance - 2000 where name = 'Tom';

-- 生成重做日志 account = 8000
update tb_finance set account = account + 2000 where name = 'Tom';

commit ;

流程
在这里插入图片描述
mysql 为了提升性能把每次修改的数据同步到磁盘,而是会先存到 Buffer Pool 中,把这个当作缓存,然后使用后台的线程将缓存刷新到磁盘。
当在执行刷新时,宕机或者断电,可能会丢失部分数据。所以引入 redo log 来记录已成功提交事务的修改信息,并且在事务提交时会把 redo log 持久化到磁盘,系统重启后再读取 redo log 恢复最新数据。

redo log 用于恢复数据,保障已提交事务的持久化特性。

undo log

undo log 叫做回滚日志,用户记录数据被修改前的信息,作用包含两个:提供回滚和 MVCC(多版本并发控制)。
redo log 相反,undo log 记录被修改前的信息。 undo log 主要记录数据的逻辑变化,可以在发生错误时将之前的记录的逻辑变化进行回滚。

原文链接:https://blog.csdn.net/weixin_44756627/article/details/126413498

栏目分类
最近更新