MySQL事务与锁

本文详细阐述了事务在数据库中的基本概念,包括事务的四大特性,以及并发带来的问题如脏读、不可重复读和幻读。讨论了SQL92中不同事务隔离级别及其在InnoDB中的实现,如MVCC和锁机制。还介绍了InnoDB中的隐藏列、undolog和ReadView等概念。
摘要由CSDN通过智能技术生成

什么是事务

事务是数据库管理系统(DBMS)执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。
事务的4大特性:

  • 原子性(Atomicity)
  • 一致性(Consistent)
  • 隔离性(lsolation)
  • 持久性(Durable)

事务并发带来的问题

脏读

一个事务读取到了另一个事务未提交的数据。
在这里插入图片描述

不可重复读

一个事务读取到了另一个事务已修改的数据。
在这里插入图片描述

幻读

一个事务读取到了另一个事务插入后的数据,导致总记录数不一致。
在这里插入图片描述

事务隔离级别

事务并发的三大问题都是数据库读一致性的问题,必须由数据库提供一定的事务隔离机制来解决。
SQL92标准

  • Read Uncommitted(未提交读):未解决任务并发问题,事务未提交的数据对其他事务可见。
  • Read Committed(已提交读):解决脏读问题,只能看到已提交的事务所做的修改,会出现不可重复读、幻读。
  • Repeatable Read(可重复读):解决不可重复读问题,同一个事务多次读取同样的数据结果一定是一致的,会出现幻读。
  • Serializable(串行):解决所有问题。

InnoDB对事务隔离级别的支持程度

事务隔离级别脏读不可重复读幻读
未提交读(Read Uncommitted)可能可能可能
已提交读(Read Committed)不可能可能可能
可重复读(Repeatable Read)不可能不可能在InnoDB中不可能
串行(Serializable)不可能不可能不可能

InnoDB事务隔离级别的实现

RRRC
普通的selectmvccmvcc
加锁的select和更新
select … in share mode
select … for update
insert
update
delete
Record Lock
Gap Lock
Next-key Lock
Record Lock

事务隔离级别区别

  1. RR的间隙锁会导致锁定范围的扩大;
  2. 条件列未使用索引时,RR锁表,RC锁行;
  3. RC的“半一致性”读可以增加update操作的并发性。

事务隔离级别解决方案

第一种

在读取数据前,对其加锁,阻止其他事务对数据进行修改(LBCC)Lock Based Concurrency Control。

第二种

生成一个数据请求时间点的一致性数据快照(Snapshot),并用这个快照来提供一定级别(语句级或事务级)的一致性读取(MVCC)Multi Version Concurrency Control。

MVCC

多版本并发控制(Multiversion Concurrency Control),它是事务隔离级别的无锁化实现方式,用于提高事务的并发效率。

隐藏列

InnoDB会为每张表生成3个隐藏列:

  • ROW_ID:6byte,如果当前表中没有主键,会默认生成一个主键ID;
  • DB_TRX_ID:6byte,最近修改(修改/插入)的事务ID,删除也被视为修改;
  • DB_ROLL_PTR:7byte,存储当前记录之前版本的存储指针,用于回滚。
    在这里插入图片描述

undolog

每次操作的历史记录都会存储在undolog文件中
在这里插入图片描述

ReadView

ReadView在事务中每次查询都会生成一个ReadView(重复读事务隔离级别只会在首次查询时创建),ReadView中有存储当前事务ID、未提交事务ID、未开始事务ID等数据,通过这些信息就可以在undolog中定位到具体的版本。
在这里插入图片描述

在MySQL中InnoDB支持表锁与行锁,MyISAM只支持表锁。
锁的类型如下:

  • 共享锁(行锁):Shared Locks
  • 排它锁(行锁):Exclusive Locks
  • 意向共享锁(表锁):Intention Shared Locks
  • 意向排它锁(表锁):Intention Exclusive Locks

共享锁(行锁)

又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是不能修改。
使用方式:

select * from employee where emp_id = 20003 LOCk IN SHARE MODE;
COMMIT/ROLLBACK;

排他锁(行锁)

又称为写锁,简称X锁,排他锁不能与其他锁并存,如一个事务获取了一条数据行的排他锁,其他事务就不能再获取该行的锁(共享锁、排他锁),只有获取了排他锁的事务可以对数据进行读取和修改操作。
使用方式:
delete/update/insert语句默认会加上X锁。

select * from employee where emp_id = 20003 for update;
COMMIT/ROLLBACK;

意向共享锁(表锁)

意向锁是由数据引擎自己维护的,用户无法手动操作意向锁。
意向锁仅仅只是给表加上一个标识,表明该表已经有行锁了,如果此时有事务需要对该表进行表锁,通过该标识判断即可,而不需要全表扫描判断该表是否有加行锁。
简称IS锁,表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先获取该表的IS锁。

意向排他锁(表锁)

简称IX锁,表示事务准备给数据行加入排他锁,说明事务在给一个数据行加排他锁前必须先获取该表的IX锁。

锁的算法

记录锁

使用唯一/主键索引等值查询时,精准匹配到一条记录。

select * from tab where id = 4 for update //锁住的就是id=4所在的记录行

在这里插入图片描述

间隙锁

查询的记录不存在时,锁住一块区间。

// 锁住(4,7)
select * from tab where id > 4 and id < 7 for update;
select * from tab where id = 6 for update;

// 锁住(10,+∞)
select * from tab where id > 15 for update;

在这里插入图片描述

临键锁

范围查询,包含记录和区间

// 锁住(4,7](7,10]
select * from tab where id > 5 and id < 9 for update;

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值