亲宝软件园·资讯

展开

MySQL中LBCC和 MVCC

dreamer'~ 人气:0

1. 事务

介绍MVCC之前,先介绍下事务:事务是为了保证数据库中数据的完整性和一致性

事务的4个基本要素:

2. MVCC初探

目的:主要是为了 提高数据库并发性能。用更好的方式去处理 读/写 冲突,做到即使有 读/写 冲突时,也能做到不加锁,非阻塞并发读。

不同隔离级别下,可能引发的问题: 脏读:并发情况下,一方事务读到了另一方事务 “已 update 但未 commit” 的数据,破坏了事务隔离性不可重复读:并发情况下,一方事务读到了另一方事务 “已 updatedelete ,并 commit ” 的数据,破坏了事务隔离性幻读:并发情况下,一方事务读到了另一方事务" insertcommit "的数据,导致前后读取结果不一致。

MVCC中的四种事务隔离级别:

提问:V1、V2、V3在不同事务隔离级别下读取到的值分别是:

3. LBCC & MVCC

LBCC 锁相关:

MySQL 5.5 版本之前,默认的存储引擎是MyISAM,5.5之后默认引擎是Innodb。Innodb支持事务,包括:行锁/表锁,MyISAM不支持。 意向锁 意向共享锁/读锁(表锁类型,无法手动创建),mysql 中语法: lock in share mode意向排它锁/写锁(表锁类型,无法手动创建),mysql 中语法: for update

常见问题:为什么要加入意向锁?

意向锁并不是真正用来锁定数据的,而是用来告诉你当前表中是否已经有了被 共享锁/排它锁
锁定的数据行
。如果有就没必要再去加无用的表锁了,起到一个标识作用,提高加表锁的效率(相当于高铁洗手间门上方是否有人正在使用的 “指示灯”)。

记录锁(Record Lock)、间隙锁(Gap Lock)、临键锁(Next-Key Lock):

问题:如图示:执行此sql语句(先开启事务):BEGIN; SELECT * FROM tbl WHERE id > 15 FOR UPDATE; ,以下两个sql语句可以执行成功吗?

MVCC底层实现详解:

快照读(实际上为相关的操作):读取的是记录的可见版本 (有可能是历史版本),不用加锁

简单的 SELECT 操作,属于快照读,不加锁。

SELECT * FROM user WHERE ? 

当前读(实际上为相关的操作):在事务中,update 数据前,还要去MySQL中重新读取一遍该数据对应最新版本的记录,并且 当前读 返回的记录都会加上锁,保证其他事务不会再并发修改这条记录。以下两种方式都属于当前读,需要加锁:

问题:在 RR-可重复读 的默认隔离级别下,假设起始的age为18,那么Q1和Q2对应的age分别是多少呢?

总结

最后,补充一个问题点:

如果不声明的创建主键,会有哪些危害? 比如你的id(假设int类型)没有声明为主键,并且也没有声明唯一索引(当未声明主键时,唯一索引会被取代为主键)

加载全部内容

相关教程
猜你喜欢
用户评论