数据库锁

简介: 数据库锁

数据库锁



锁和索引是数据库两大核心概念,了解索引,可以从 B+ 树,Hash 索引,页结构,缓存池,索引原则等方面理解。理解锁,要从哪些方面入手?


为什么要加锁


加锁的目的,其实是为了保证数据的一致性。当多个线程并发访问某个数据时,加锁,可以保证这个数据在任何时刻最多只有一个线程在访问,保证数据的完整性和一致性。


锁的分类


锁可以按照锁粒度划分,可以按照数据库管理角度划分。


按照锁粒度划分


按照锁粒度划分,可以将锁划分成 行锁,页锁和表锁。

快速回忆一遍 InnoDB 存储引擎的逻辑结构:所有数据都被逻辑地存放在一个空间内,称为表空间,而表空间由段(sengment)、区(extent)、页(page)组成。


640.png


  1. 行锁

行锁,就是按照行的粒度对数据进行锁定,锁定粒度小,发生锁冲突概率低,可以实现并发都高,但是对于锁的开销比较大,加上会比较慢,容易出现死锁的情况。

  1. 页锁

页锁就是页的粒度上进行锁定,锁定的数据资源比行锁要多,因为一个页中可以有多个行记录,当我们使用页锁的时候,会出现数据浪费的现象,页锁的开销介于表锁行锁之间。

  1. 表锁

表锁就是对数据进行锁定,锁定粒度很大,发送锁的概率很高,数据访问的并发度。不过好处在于对锁的使用开销小,加锁会很快。

InnoDB 和 Oracle 支持行锁和表锁,MyISAM 只支持表锁, MYSQL BDB 存储引擎支持页锁和表锁。SQL Server 可以支持行锁,页锁和表锁。


640.png

按照数据库管理角度划分


按照数据库管理角度划分,可以将锁分成排他锁和共享锁。

  1. 共享锁

共享锁,也叫读锁,或者 S 锁,共享锁锁定的资源可以被其他用户读取,但不能修改。在进行 SElECT 的时候,会将对象进行共享锁锁定,当数据读取完毕之后,就会释放共享锁,这样就可以保证数据在读取时不被修改。

给某个表加共享锁


LOCK TABLE product_comment READ;

当数据表加上共享锁的时候,该表数据就会变成只读模式,当时我们想更新 product_comment 表中的数据会报错,比如:


UPDATE product_comment SET product_id = 10002 WHERE user_id = 912178;

系统报错如下:


ERROR 1099 (HY000): Table 'product_comment' was locked with a READ lock and can't be updated

如果对表共享锁进行解锁:


UNLOCK TABLE;

给某行数据加共享锁


SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE

例子:


SELECT comment_id, product_id, comment_text, user_id FROM product_comment WHERE user_id = 912178 LOCK IN SHARE MODE
  1. 排他锁

排他锁也叫做独占锁,写锁或者 X 锁,排他锁锁定的数据只允许进行锁定操作的事务使用,其他事务无法对已锁定的数据进行查询或者修改。


给表加排他锁


LOCK TABLE product_comment WRITE;

排他锁的事务可以对 product_comment 进行查询和修改。其他事务如果想要在 product_comment 表上查询数据,则需要等待。

释放掉排他锁

UNLOCK TABLE;

数据行上添加排他锁

SELECT * FROM table_name WHERE ... FOR UPDATE

例子:

SELECT comment_id, product_id, comment_text, user_id FROM product_comment WHERE user_id = 912178 FOR UPDATE;

当我们对数据进行更新的时候会自动使用排他锁,也就是 INSERT ,DELETE 或者 UPDATE 的时候,数据库自动使用排他锁,防止其他事务对改数据进行操作。


从程序员角度进行划分


  1. 乐观锁

乐观锁认为对同一个数据并发操作不会总发生,是小概率事件,因此不用每次对数据进行更新或者删除。


UPDATE ... SET version=version+1 WHERE version=version


此时,如果已经有事务对这条数据进行了更新,修改就不会成功。

640.png


  1. 悲观锁

悲观锁(Pessimistic Locking),通过数据库自身的锁机制来实现,从而保证数据操作的排他性。

  • 乐观锁适合读操作多的场景,相对来说写的操作⽐较少。它的优点在于程序实现,不存在死锁问题,不过适⽤场景也会相对乐观,因为它阻⽌不了除了程序以外的数据库操作。
  • 悲观锁适合写操作多的场景,因为写的操作具有排它性。采⽤悲观锁的⽅式,可以在数据库层⾯阻⽌其他事务对该数据的操作权限,防⽌读-写和写-写的冲突


640.png

640.png

相关文章
|
6月前
|
SQL 存储 关系型数据库
【MySQL 数据库】11、学习 MySQL 中的【锁】
【MySQL 数据库】11、学习 MySQL 中的【锁】
125 0
|
6月前
|
存储 关系型数据库 MySQL
了解MySQL 数据库的锁机制
了解MySQL 数据库的锁机制。
63 0
|
6月前
|
供应链 数据库 开发者
深入了解数据库锁:类型、应用和最佳实践
深入了解数据库锁:类型、应用和最佳实践
|
6月前
|
存储 关系型数据库 MySQL
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
1060 0
|
存储 关系型数据库 MySQL
Mysql数据库—事务和锁
Mysql数据库—事务和锁
|
5月前
|
SQL 关系型数据库 MySQL
MySQL数据库进阶第五篇(锁)
MySQL数据库进阶第五篇(锁)
|
1月前
|
存储 关系型数据库 MySQL
MySQL数据库锁:共享锁和独占锁
本文详细介绍了`InnoDB`存储引擎中的两种行级别锁:共享锁(S锁)与排他锁(X锁)。通过具体示例展示了这两种锁的工作机制及其在`InnoDB`与`MyISAM`引擎中的表现差异。文章还提供了锁的兼容性矩阵,帮助读者更好地理解锁之间的互斥关系。最后总结了两种锁的特点及适用场景。适合希望深入了解`MySQL`并发控制机制的读者阅读。
51 1
|
6月前
|
SQL 关系型数据库 数据库
OceanBase数据库常见问题之密码输入错误次数多被锁了如何解决
OceanBase 是一款由阿里巴巴集团研发的企业级分布式关系型数据库,它具有高可用、高性能、可水平扩展等特点。以下是OceanBase 数据库使用过程中可能遇到的一些常见问题及其解答的汇总,以帮助用户更好地理解和使用这款数据库产品。
|
3月前
|
SQL 存储 关系型数据库
"MySQL增列必锁表?揭秘InnoDB在线DDL,让你的数据库操作飞一般,性能无忧!"
【8月更文挑战第11天】在数据库领域,MySQL凭借其稳定高效的表现深受开发者喜爱。对于是否会在给数据表添加列时锁表的问题,MySQL的行为受版本、存储引擎等因素影响。从5.6版起,InnoDB支持在线DDL,可在改动表结构时保持表的可访问性,避免长时间锁表。而MyISAM等则需锁表完成操作。例如,在使用InnoDB的表上运行`ALTER TABLE users ADD COLUMN email VARCHAR(255);`时,通常不会完全锁表。虽然在线DDL提高了灵活性,但复杂操作或大表变更仍可能暂时影响性能。因此,进行结构变更前应评估其影响并择机执行。
72 6
|
3月前
|
SQL 数据库
无法获得数据库 'model' 上的排他锁。请稍后重试该操作
无法获得数据库 'model' 上的排他锁。请稍后重试该操作
81 0