mysql数据库锁简介
作者:互联网
本篇介绍有关数据库锁相关的知识,关于数据库事务及隔离级别参见《数据库事务ACID特性及隔离级别》这篇文。
乐观锁
乐观锁最常用的实现方式是用数据版本(Version)记录机制。数据版本即为数据增加一个版本标识,一般通过在数据库表中增加一个数字类型的 “version” 字段实现。读取数据时将version字段值一同读出,数据每更新一次,对version值加1,提交更新时将数据库表对应记录的当前version值与已取出的version值进行比对,如果数据库表当前version值与已取出的version值相等,则可以更新,否则认为是过期数据。
通常在实际项目中涉及金钱类的可能会使用这种乐观锁。
举例:
1、数据库表三个字段,分别是id、value、version
select id,value,version from table1 where id = #{id}
2、每次更新表中的value字段时为了防止发生冲突,需要这样操作
update table1
set value=2,version=version+1
where id=#{id} and version=#{version}
悲观锁
悲观锁认为在操作数据时会出现数据冲突,每次都要通过获取锁才能对相同数据进行操作,所以悲观锁需要耗费较多的时间。共享锁 和 排它锁 是悲观锁的不同实现,都属于悲观锁的范畴。
1、锁的粒度
InnoDB默认采用行锁,在未使用索引字段查询时升级为表锁。行锁可能因为未使用索引而升级为表锁,所以除了检查索引是否创建的同时,也需要通过explain执行计划查询索引是否被实际使用。
2、读写锁3、意向锁(Intention Locks)
为了实现多粒度锁机制,协调 行级读写锁 和 表级读写锁 (也就是不同粒度)之间的关系。意向锁是一种允许 行锁 与 表锁 共存的表锁。意向锁是由数据库引擎维护的,用户无法手动操作。在为数据行加 共享锁 / 排它锁 之前,InooDB 会先获取该数据行所在数据表的对应 意向锁。意向锁只会阻塞全表请求,主要目的是展示正在锁定表中一行,或者将要锁定一行。 意向锁分为两种: 意向共享锁(intention shared lock, IS):事务有意向对表中的某些行加共享锁(S锁) -- 事务要获取某些行的 S 锁,必须先获得表的 IS 锁。 SELECT column FROM table1 ... LOCK IN SHARE MODE; 意向排它锁(intention exclusive lock, IX):事务有意向对表中的某些行加排它锁(X锁) -- 事务要获取某些行的 X 锁,必须先获得表的 IX 锁。 SELECT column FROM table1 ... FOR UPDATE; 意向锁不会与行级的 共享/排它锁 互斥。1) InnoDB 支持多粒度锁,特定场景下,行级锁 可以与 表级锁 共存。
2) 意向锁之间互不排斥,但除了 IS 与 S 兼容外,意向锁会与 共享锁 / 排它锁 互斥。 3) IX,IS是表级锁,不会和行级的X,S锁发生冲突。只会和表级的X,S发生冲突。 4) 意向锁在保证并发性的前提下,实现了行锁和表锁共存且满足事务隔离性的要求。 4、记录锁(Record Locks) 记录锁是在索引记录上的锁。例如,SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; 防止任何其他事务 插入、更新 或 删除 t.c1=10 的行。 5、间隙锁(Gap Locks) 间隙锁(gap)是索引记录之间上的锁,或者说第一个索引记录之前或最后一个索引记录之后的间隔上的锁。例如,SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; 阻止其他事务插入 t.c1 = 15 的记录,不管是否已经有这种值在本列中,因为这个范围内的所有值都被上锁了。 6、NK锁(Next-Key Locks) NK锁是记录锁和间隙锁的组合,锁定一个范围,并且锁定记录本身。对查询范围进行加锁,在另一个事务执行插入操作时是不被运行的,从而避免了幻读。用于解决幻读问题。 InnoDB默认的事务隔离级别是Repeatable Read,此时InnoDB使用NK锁进行搜索和索引扫描,防止产生幻读。 7、插入意向锁(Insert Intention Locks) 插入意向锁是在插入一条记录行前,由 INSERT 操作产生的一种间隙锁。该锁用以表示插入意向,当多个事务在同一区间(gap)插入位置不同的多条数据时,事务之间不需要互相等待。 插入意向锁本质上可以看成是一个间隙锁(Gap Lock)。 普通的Gap Lock 不允许 在(上一条记录,本记录)范围内插入数据 插入意向锁Gap Lock 允许 在(上一条记录,本记录)范围内插入数据 插入意向锁的作用是为了提高并发插入的性能, 多个事务 同时写入 不同数据 至同一索引范围(区间)内不需要等待其他事务完成,不会发生锁等待。 InnoDB 在 Repeatable Read 的事务隔离级别下,使用插入意向锁来控制和解决并发插入。 8、自增锁(AUTO-INC Locks) 自增锁是由插入到具有AUTO_INCREMENT列的表中的事务所采用的特殊表级锁。 在最简单的情况下,如果一个事务正在向表中插入值,任何其他事务必须等待,以便这个事务获得连续的主键值。标签:事务,记录,索引,简介,数据库,插入,version,意向锁,mysql 来源: https://www.cnblogs.com/aiandbigdata/p/10488308.html