
mysql事务与锁
发布日期:2021-05-08 05:28:13
浏览次数:23
分类:原创文章
本文共 2260 字,大约阅读时间需要 7 分钟。
事务四大特征
- 原子性 Atomicity
- 一致性 Consistent
- 隔离性 Isolation
- 持久性:Durable
- redo log + double write(防止磁盘损坏不能写日志),双写缓冲
如何开启/结束事务
- set session autocommit = on/off; – 设定事务是否自动开启
- begin / start transaction – 手工方式(会获得锁)
- commit / rollback – 事务提交或回滚(会释放锁,关闭客户端连接也会释放锁)
事务并发三大问题
- 脏读(第一个回话查询出来的第二次数据有可能是,第二个回话回滚的数据)
- 不可重复度(第二个会话update/delete 并commit,第一个回话同一个事务两次查询数据不一致)
- 幻读(第二个事务insert,第一个回话同一个事物 再次查询一个范围发现这个位置多冒出来一条数据)
事务的四种隔离级别
- Read Uncomminted未提交读 – 没解决任何事情
- Read Committed已提交读 – 解决脏读
- Repeatable Read可重复读 – 解决不可重复读(事实上MVCC Next-key Lock(临键锁) = Gap lock(间隙锁) + Record lock(记录锁) 解决幻读)
- Serializable串行化 – 解决所有问题
MySQL InnoDB对事务隔离级别的支持程度
- 事务隔离级别设置为可重复度 可以解决幻读问题
- ,InnoDB 在 RR 的级别就解决了幻读的问题。这个也是 InnoDB 默认使用 RR 作为事务隔离级别的原因,既保证了数据的一致性,又支持较高的 并发度
事务隔离级别解决方案:
- 在读取数据前,对其加锁,阻止其他事务对数 据进行修改(LBCC) Lock Based Concurrency Control。
- 生成一个数据请求时间点的一致性数据快照 (Snapshot),并用这个快照来提供一定级别(语句级或事 务级)的一致性读取(MVCC)Multi Version Concurrency Control。
MVCC (只能查找创建时间小于等于当前事务id的数据,和删除时间大于当前事务id的行(或未删除)),也就是说:在之前创建的数据是可以查得到,之后删除的也能查得到
- DB_TRX_ID,6字节:插入或更新行的最后一个事务的事务 ID,事务编号是自动递增的(创建版本)。
- DB_ROLL_PTR,7字节:回滚指针(删除版本)
MySQL InnoDB 锁类型
- 共享锁(行锁):share locks
- 加锁释锁方式: select * from student where id=1 LOCK IN SHARE MODE;
- 释放锁:commit/rollback;
- 排它锁(行锁):Exclusive locks
- 排他锁不能与其他锁并存,如一个事务获取 了一个数据行的排他锁,其他事务就不能再获取该行的锁(共享锁、排他 锁)
- 加锁释锁方式:
- 自动:delete / update / insert 默认加上X锁
- 手动:select * from student where id=1 FOR UPDATE;
- 释放:commit/rollback
- 意向共享锁(表锁):Intention share locks
- 意向排它锁(表锁):Intention Exclusive Locks
意向共享锁(IS)/ 意向排它锁(IX):
- 意向锁是由数据引擎自己维护的,用户无法手动操作意向锁
- 加意向锁时相当于为这个表添加了一个标志
锁的原理探究
- 当不加索引时,锁一行数据,其他会话(事务)对整个表加不了锁,也就是锁表了(没用到索引默认把全部RowID锁住)
- 添加主键索引时,
- 没锁表
- 因为是通过辅助索引检索数据,再检索主键索引,索引锁了辅助索引,也锁了主键索引
- 但是用其他索引列(唯一索引)(或者没索引的列)查找依然锁行
- 覆盖索引不会被锁
锁
- 记录锁(record lock)
- 锁记录
- 间隙锁(Gap lock)
- 锁范围
- 主要阻塞插入,再次执行select * for update 也会执行成功,不会卡住
- 临键锁(next key lock ),
- 解决幻读,把区间后面的数据也锁住的话 后面就不能插入数据
- Next-key Lock = Gap lock + Record lock
- 连最后一个记录一下一个值也会被锁住,入 id >5 and id<9 后面有10 的话,10也会被锁住
事务隔离级别的实现
- Read Uncommited 不加锁
- Serializable
- 所有的select语句都会被隐式的转化为select … in share mode,会和 update、delete互斥
死锁的避免
1)顺序访问 2)数据排序 3)申请足够级别的锁 4)避免没有where条件的操作 5)大事务分解成小事务 6)使用等值查询而不是范围查询
事务的原子性、隔离性、持久性通过什么技术实现
- 原子性通过回滚来实现,undo log,记录了数据修改之前的日志,一旦发生异常,可以通过undolog 回滚
- 隔离性,实现主要有读写锁 和mvcc,mvcc方式由于其读写不冲突,效率更高
- 持久性:通过redo log 和double write 双写缓冲,一旦磁盘发生损坏,能够让redo log恢复
四种事务隔离级别与事务并发带来的问题的关系(innodb)
发表评论
最新留言
表示我来过!
[***.240.166.169]2025年04月10日 11时01分32秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
爬取网易科技滚动新闻
2021-05-08
vuex modules
2021-05-08
vue父子组件传参的4种方式
2021-05-08
中缀表达式转后缀表达式
2021-05-08
Java笔记:单链表
2021-05-08
phthon基本语法——温习
2021-05-08
sleep、wait、yield、join——简介
2021-05-08
web项目配置
2021-05-08
VTK:相互作用之Picking
2021-05-08
VTK:Medical之MedicalDemo2
2021-05-08
c语言(基本数据类型)实参与形参传值 用汇编理解
2021-05-08
基于单片机可控音乐流水灯控制设计-全套资料
2021-05-08
基于单片机简易信号误差分析设计-全套资料
2021-05-08
基于单片机简易脉搏测量仪系统设计-毕设课设资料
2021-05-08
并发框架下的“基础类型”——浅析基本类型、ThreadLocal、原子类的线程安全机制
2021-05-08
Android Studio同步Gradle失败的解决办法
2021-05-08
VHDL代码风格
2021-05-08
图像处理系列1.skimage
2021-05-08
读取二进制存储信息,将低位二进制存储转换为高位存储
2021-05-08