一方面要最大程度地利用数据库的并发访问,另外一方面还要确保每个用户能以一致的方式读取和修改数据。
为此就有了锁(locking)的机制,同时这也是数据库系统区别于文件系统的一个关键特性.
锁机制用于管理对共享资源的并发访问.
对于MyISAM引擎,其锁是表锁设计。并发情况下的读没有问题,但是并发插入时的性能就要差一些了,若插入是在“底部”,MyISAM存储引擎还是可以有一定的并发写入操作。
InnoDB存储引擎锁的实现和Oracle数据库非常类似,提供 一致性的 非锁定读、行级锁支持
。行级锁没有相关额外的开销,并可以同时得到并发性和一致性。
lock的对象是事务,用来锁定的是数据库中的对象,如表、页、行。
并且一般lock的对象仅在事务commit或rollback后进行释放(不同事务隔离级别释放的时间可能不同)。此外,lock,正如在大多数数据库中一样,是有死锁机制的。
可以通过命令 SHOW ENGINE INNODB STATUS
及information_schema架构下的表INNODB_TRX、INNODB_LOCKS、INNODB_LOCK_WAITS来观察锁的信息。
InnoDB存储引擎中的锁
锁的类型
InnoDB存储引擎实现了如下两种标准的 行级锁
:
❑共享锁(S Lock),允许事务读一行数据。
❑排他锁(X Lock),允许事务删除或更新一行数据。
如果一个事务T1已经获得了行r的共享锁,那么另外的事务T2可以立即获得行r的共享锁,因为读取并没有改变行r的数据,称这种情况为锁兼容(Lock Compatible)。
但若有其他的事务T3想获得行r的排他锁,则其必须等待事务T1、T2释放行r上的共享锁——这种情况称为锁不兼容
表6-3显示了共享锁和排他锁的兼容性。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uyaYmbWy-1617298383741)(assets/2021-04-01-09-15-19.png)]
X锁与任何的锁都不兼容,而S锁仅和S锁兼容。
需要特别注意的是,S和X锁都是行锁,兼容是指对同一记录(row)锁的兼容性情况。
此外,InnoDB存储引擎支持多粒度(granular)锁定,这种锁定允许事务在 行级上的锁 和 表级上的锁
同时存在。
为了支持在不同粒度上进行加锁操作,InnoDB存储引擎支持一种额外的锁方式,称之为意向锁(Intention Lock)。
意向锁是将锁定的对象分为多个层次,意向锁意味着事务希望在更细粒度(fine granularity)上进行加锁
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nomjFbqH-1617298383743)(assets/2021-04-01-09-21-29.png)]
若将上锁的对象看成一棵树,那么对最下层的对象上锁,也就是对最细粒度的对象进行上锁,那么首先需要对粗粒度的对象上锁。
如果需要对页上的记录r进行上X锁,那么分别需要对数据库A、表、页上意向锁IX,最后对记录r上X锁。
若其中任何一个部分导致等待,那么该操作需要等待粗粒度锁的完成。
举例来说,在对记录r加X锁之前,已经有事务对表1进行了S表锁,那么表1上已存在S锁,之后事务需要对记录r在表1上加上IX,由于不兼容,所以该事务需要等待表锁操作的完成。
InnoDB存储引擎支持意向锁设计比较简练,其意向锁即为表级别的锁。
设计目的主要是为了在一个事务中揭示下一行将被请求的锁类型。其支持两种意向锁:
1)意向共享锁(IS Lock),事务想要获得一张表中某几行的共享锁
2)意向排他锁(IX Lock),事务想要获得一张表中某几行的排他锁