3

mysql锁机制知识整理

 2 years ago
source link: https://dawnki.github.io/2017/08/08/%E6%B5%85%E8%B0%88mysql%E9%94%81%E6%9C%BA%E5%88%B6/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

并发处理时我们经常谈到的问题。在数据库操作中,有时候需要考虑并发的问题,比如我们常见的库存管理系统以及银行转账等问题,这些场景都需要用到数据库的锁机制以及事务,不然很容易造成”脏数据”等常见的在并发中遇到的问题。今天浅谈一下mysql锁机制。

表级锁与行级锁

Mysql的锁机制大概分为两种,一种是表级锁,一种是行级锁。顾名思义,表级锁就是在进行读写操作时,把涉及到的目标表锁住,阻塞其他连接对相关表的操作。行级锁就是粒度更细了,精确到了表里的某条纪录。

表级锁 行级锁

开销 少 大

冲突 高 低

是否可能死锁 否 是

并发度 低 高

Mysql中的Innodb引擎支持行级锁以及表级锁,MyIsam只支持表级锁。表级锁中,当一个连接给一个加锁后,只能访问或者修改加锁的表,而不能再访问其他表了,除非解锁,这就破坏了死锁中的占有且等待条件,因而不用担心造成死锁的问题。

更新丢失(Lost Update):简单来说就是两个连接(事务)同时对一行进行更新,最后导致了晚一点点更新的会覆盖掉之前更新的。解决办法就是在一个连接进行更改操作时,不允许其他连接访问就可以避免更新丢失的问题。

脏读(Dirty Reads):一个事务对一条记录进行修改时(未提交),此时其他事务对这条记录进行读操作,导致读取的是旧数据,非最新的修改数据,因而数据脏读。

不可重复读(Non-Repeatable Reads):一个事务在读取某些数据后的某个时间,再次读取之前读过的数据,但是数据可能已经发生更改,之前读到的数据不一致。

幻读(Phantom Reads):一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。

InnoDB的行锁模式及加锁方法

共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。

排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。另外,为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁。

意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。

意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。

InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过 索引 条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁.

  1. 如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。
  2. 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率。
  3. 对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率。

Mysql中那些锁机制之InnoDB


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK