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)

上一篇:jvm-02
下一篇:jvm-01

发表评论

最新留言

表示我来过!
[***.240.166.169]2025年04月10日 11时01分32秒