MySQL - 锁

1. 锁

提到锁,一般都是因为存在竞争条件(Race Condition)而导致结果不可预测。比如两个线程同时修改某个值,最终这个值的结果是什么有多种可能性。如果加入锁,在线程访问修改某个值的时候,可以禁止其他线程同时访问修改这个值,这样就避免了多种结果的可能性。

MySQL Innodb的锁的最小单位是行锁,基于索引(Index)实现,加锁的时候是在B+树索引结构的节点上加锁。所以如果某个字段没有索引,然后用户通过这个字段进行查找来更新数据的时候就会导致整个表(其实是整个聚类索引的叶子结点)被加锁;如果用户通过聚类索引的字段进行查找,则只对索引查找结果的叶子节点加锁;如果用户通过二级索引字段进行查找,则除了对二级索引加锁,还会对聚类索引加锁。

2. 事务

事务具有ACID特性:分别是原子性(atomicity),一致性(consistency),隔离性(isolation),和持久性(durability)
原子性(atomicity)是指一个事务内的操作要不全被commit,要不整个rollback。
一致性(consistency)是指系统始终处于一致的状态,事务操作只会使系统从一个状态变幻到另一个一致的状态。
隔离性(isolation)是指各个事务之间是独立的,隔离的,彼此不会相互影响。
持久性(durability)是指事务提交之后数据持久保存在数据库系统中。

3. 数据库的隔离级别

数据库的隔离级别(Isolation level)分为:未提交读(Uncommit Read),提交读(Commit Read),可重复读(Repeatable Read)和可串行化(Serializable)

在了解隔离级别之前先来看看InnoDB读的分类:快照读(snapshot read)现读(current read)
一般的SELECT都是快照读,其他的读都属于现读,比如SELECT * FROM tableName FOR SHARE。快照读不加锁,根据隔离级别的不同读取策略也不同;现读会加S锁(共享锁)或者X锁(互斥锁),其中SELECT ... FOR SHARE会加S锁,其他情况都是加X锁。

未提交读(Uncommit Read)就是快照读可以读取事务内修改了但是未提交的值,这种情况下就会产生脏读。一般不会考虑设置为数据库隔离级别。
提交读(Commit Read)就是快照读只可以读取提交之后的数据。这样就消除了脏读的产生,但是会有幻读产生的可能性。所谓幻读就是本来要修改了年龄等于20的用户的表信息,事务提交之后发现有些“没有修改成功”,因为有线程在上述事务期间插入了年龄为20的新用户信息,这样会有一种操作未成功的错觉。是MySQL的默认隔离级别。
可重复读(Repeatable Read)的隔离级别下除了一般的行锁,也会同时加上间隙锁(gap lock)。间隙锁防止了幻读的产生:上例中age为20的B+树节点之间和范围前后节点之间也会被加锁,导致age为20的新数据无法插入。
可串行化(Serializable)的隔离级别下,快照读不复存在,所有的读都是现读。读写冲突,导致性能下降。一般不会考虑设置为数据库隔离级别。

4. 死锁以及如何避免死锁

Reference

hedengcheng.com/?p=771

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • MySQL 加锁处理分析 转载2013年12月13日 16:43:55 7598 原文地址:http://hede...
    初来的雨天阅读 537评论 0 2
  • 背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题。我在工作过程中,经常会有同事咨询这方面的问题。...
    MakeACoder阅读 662评论 0 3
  • 当一个系统访问量上来的时候,不只是数据库性能瓶颈问题了,数据库数据安全也会浮现,这时候合理使用数据库锁机制就显得异...
    初来的雨天阅读 3,699评论 0 22
  • InnoDB 锁 数据库使用锁是为了支持更好的并发,提供数据的完整性和一致性。InnoDB是一个支持行锁的存储引擎...
    大富帅阅读 1,898评论 0 4
  • MySQL的事务支持 MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关: MyISAM:不支...
    但莫阅读 617评论 0 6

友情链接更多精彩内容