Mysql中的锁和MVCC整理


目录

  1. Mysql事务和锁

    1.1 快照读和当前读

    1.2 行锁与表锁

    1.3 排他锁和共享锁

    1.4 乐观锁和悲观锁

  2. Mysql乐观锁和悲观锁的实现

    2.1 悲观锁

    2.2 乐观锁

Mysql事务和锁

ACID中,Innodb的隔离性是通过锁和MVCC来保证的。
MySql的锁机制

快照读和当前读

当前读就是读的是当前时刻已提交的数据,快照读就是读的是快照生成时候的数据。
在默认隔离级别下,select 语句默认是快照读

select a from t where id = 1 

select 语句加锁是当前读

# 共享锁 
select a from t where id = 1 lock in share mode;

#排他锁
select a from t where id = 1 for update; 

update 语句是当前读

update t set a = a + 1;

行锁与表锁

innodb加行锁的前提是:必须是通过索引条件来检索数据,否则会切换为表锁。

排他锁和共享锁

共享锁(S)和排他锁(X)。共享锁允许一个事务读数据,不允许修改数据,如果其他事务要再对该行加锁,只能加共享锁;排他锁是修改数据时加的锁,可以读取和修改数据,一旦一个事务对该行数据加锁,其他事务将不能再对该数据加任务锁。

乐观锁和悲观锁

都是针对读(select)来说的,而且是用户端在编写业务时候的实现方式,和mysql原理没有什么关系

Mysql乐观锁和悲观锁的实现

悲观锁

其实就是加排他锁
Demo:

  • 程序A在查询库存数时使用排他锁 select * from table where id=10 for update
  • 然后进行后续的操作,包括更新库存数,最后提交事务。
  • 程序B在查询库存数时,如果A还未释放排他锁,它将等待……
  • 程序C同B……(也等待中..)

乐观锁

使用乐观锁(靠表设计和代码来实现)

  • 一般是在该商品表添加version版本字段或者timestamp时间戳字段
  • 程序A查询后,执行更新变成了:update table set num=num-1 where id=10 and version=23

这样,保证了修改的数据是和它查询出来的数据是一致的(其他执行程序肯定未进行修改)。当然,如果更新失败,表示在更新操作之前,有其他执行程序已经更新了该库存数,那么就可以尝试重试来保证更新成功。为了尽可能避免更新失败,可以合理调整重试次数(阿里巴巴开发手册规定重试次数不低于三次)。

参考文档:https://www.cnblogs.com/fangdada/p/15097287.html
乐观锁住要通过版本号和CAS算法2种方式进行实现


文章作者: 小小千千
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小小千千 !
评论
  目录