赞
踩
当多个用户并发存取数据时,在数据库中会产生多个事务同时存取同一数据的情况,若不对并发操作加以控制就可能导致读取和存储的数据不正确,破坏数据的一致性,加锁的目的就是为了保证数据库的完整性和一致性。
在关系型数据库中可以分为:表级锁,页级锁,行级锁
表级锁:是mysql中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,实现简单,资源消耗较少,大部分mysql引擎支持,如InnoDB,Myisam。表级锁的开销小,加锁快,不会出现死锁;但锁的粒度大,发生锁冲突的概率高,并发度最低。表级锁又分为共享锁(读锁)与排他锁(写锁)。
按照锁的类别来分,数据库有:
共享锁:又称为读锁,当用户要进行数据的读取时,对数据加上共享锁,共享锁可以加上多个
排他锁:又称为写锁,当用户要进行数据的写入时,对数据加上排他锁,排他锁只可以加一个,
它与其他排他锁,共享锁都相斥。
页级锁:页级锁是mysql中所粒度介于表级锁和行级锁之间的一种锁。表级锁速度快,但冲突多,行级锁冲突少,但速度慢。页级锁折中介于两者之间,一次锁定相邻的一组记录。BDB引擎支持页级锁。开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
行级锁:行级锁是mysql中所粒度最小的一种锁,表示对当前操作的行进行加锁,锁的粒度小,加锁开销大,锁冲突概率最低,并发度最高。InnoDB引擎支持。
数据库的管理系统中的并发控制的任务是确保多个事务同时存取数据中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性,乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。
乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。在修改数据的时候把事务锁起来,通过version的方式来进行锁定。实现方式:一般会使用版本号机制或CAS算法实现。
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。在查询完数据的时候就把事务锁起来,直到提交事务。实现方式:使用数据库中的锁机制
应用场景:乐观锁常用于多读的场景下,悲观锁常用于多写的场景下。
InnoDB是基于索引来完成行锁
例: select * from tab_with_index where id = 1 for update;
for update 可以根据条件来完成行锁锁定,并且 id 是有索引键的列,如果 id 不是索引键那么InnoDB将完成表锁,并发将无从谈起
死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象。通俗来讲:有一块蛋糕,两个人一人抢到一半,并且这两个人还在要求对方将自己手里的另一半也给自己,相互拉扯。
常见的解决死锁的方法
1、如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低思索的机会。
2、在同一事物中尽可能做到一次锁定所需要的所有资源,减少死锁产生的概率。
3、对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;
如果业务处理不好可以用分布式事务锁或者使用乐观锁
在读未提交级别下,读取数据不需要加共享锁,这样就不会与被修改的数据上的排他锁冲突
在读已提交级别下,读操作需要加共享锁,但是在语句执行完以后释放共享锁;
在可重复读级别下,读操作需要加共享锁,但是在事务提交之前并不释放共享锁,也就是必须等待事务执行完毕以后才释放共享锁。
可串行化是限制性最强的隔离级别,因为该级别锁定整个范围的键,并一直持有锁,直到事务完成
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。