本文共 2303 字,大约阅读时间需要 7 分钟。
当数据库有并发事务的时候,可能会产生数据不一致,这时候就需要一些机制来保证访问的次序,锁机制就是这样的一个机制
在关系型数据库中,可以按照锁的粒度把数据库锁分为行级锁、表级锁和页级锁,这三种锁是根据锁的粒度来区分的,行记录、表、页都是资源,锁是作用在这些资源上的,如果粒度比较小,可以增加系统的并发量,但是需要比较大的系统开销,会影响到性能,出现死锁
MyISAM和InnoDB存储引擎使用的锁:
从锁的类别上来讲,有共享锁和排他锁:
这里存在一个误区:以为排他锁锁住一行数据后,其他事务就不能再读取和修改该行数据。但其实不是这样的,排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁。
在InnoDB引擎中,默认的修改数据语句(update、insert、delete)都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁的类型,总的来说:排他锁是指在给某行数据加上排他锁之后,其他事务不能再给该行数据加任何的排他锁和共享锁,但如果某条语句只是进行查询,但是不给该行加任何锁,那么该语句也是可以查询到该行数据的
数据库中的数据存放是分级的,类似于表——页——记录这样的存储
现在举个例子: 事务A锁住了表中的一行,让这一行只能读,不能写。之后,事务B申请整个表的写锁,如果事务B申请成功,那么它将获得修改整个表的权限,这样和事务A是有冲突的,那么怎么解决这个冲突呢在没有意向锁的情况下:
在步骤二中,共享锁和排他锁都是行级锁,也就是说每次事务都必须遍历整个表,才知道是否可以获取该行上的锁,效率太低,所以为了减少这样的查询,所以MySQL支持多粒度锁定
MySQL支持多粒度锁定,也就是说允许行级锁和表级锁同时存在,而为了支持这种多粒度锁定,引入了意向锁当有了意向锁之后,那么上面的例子又会变成什么样的:
意向锁分类:
意向锁概述:
InnoDB行锁是通过给索引上的索引项加锁来实现的,InnoDB这种行锁实现特点以为着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁,也就没有所谓的并发(因为InnoDB将整张表都锁定了)
死锁是指两个或多个事务在统一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象
常见的解决死锁的办法:
数据库管理系统中的并发控制的任务是确保在多个事务同时存取数据库中统一数据时不破坏事物的隔离性和统一性
悲观锁的特点就是先获取锁,再进行业务操作,“悲观”就是认为获取锁是非常可能失败的,因此要先确保获取锁成功再进行业务操作,通常来讲,在数据库上的悲观锁需要数据库本身提供支持,即通过常用的select…… for update操作来实现悲观锁。悲观锁的实现方式:使用数据库中的锁机制
假设不会发生并发冲突,只是在提交操作时检查是否违反数据完整性。在修改数据的时候把数据锁起来
转载地址:http://jhjmb.baihongyu.com/