> 文章列表 > mysql锁的相关知识

mysql锁的相关知识

mysql锁的相关知识

下面的所有例子都以一个下面这表为例

CREATE TABLE `blog` (`id` int NOT NULL AUTO_INCREMENT,`title` varchar(255) DEFAULT NULL,`link` varchar(255) DEFAULT NULL,`publish_time` varchar(255) DEFAULT NULL,`version` int NOT NULL,`read_count` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=202 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |

mysql锁的概念有很多,悲观锁,乐观锁,行锁,排他锁。。。。,但是请注意,这些概念并不是一个层级的。就像人里面有男人,女人,老人,小孩,公务员,农民等等。

悲观锁与乐观锁

从逻辑概念上来讲,锁分为两种
乐观锁与悲观锁.

所谓乐观锁,就是我乐观的认为,我在写数据的大概率不会发生并发的问题。
所谓悲观锁,就是我认为,我写数据的时候,大概率会发生并发的问题。
从使用上来说
悲观锁,可以通过给sql加上for update这个语句来实现
乐观锁是使用version来辅助执行

  • 悲观锁
    先说明,使用for update语句的时候,得保证两点
    1 所用的存储引擎是InnoDB
    2 并且必须开启事务,在begin与commit之间才生效。
    举个例子
start transaction;select * from blog where id=62 for update;
update blog set title='new_update' where id=62;commit;

如果线程A使用上面的语句,在执行到commit之前,线程B发送了下面的语句

update blog set title='new_update2' where id=62;

那最终的结果就是,只要线程A没有commit,线程B的语句就一直卡着不执行。
另外,问一句,如果线程B执行的也只是select操作,并不修改数据,那么线程B可以立即执行么?答案是可以。

  • 乐观锁
    乐观锁的实现,就是加一个version,每次写之前,先读到version,然后写的时候指定version。
select version from blog
update blog set title="xxx",version=version+1 where id=xx,version={version};

行锁,表锁

从锁的范围上来说,锁分行锁,表锁。
什么意思呢?
如果线程A对某张表加了表锁,那么别的线程就不能写这张表了。
如果线程A对某张表的某些行加了行锁,那别的线程就不能修改这几行了。
那常见的sql里面,哪些语句会加行锁,哪些语句会加表锁呢?
例如

update blog set title='xx' where id=13

如上,更新的时候走了索引,那就只锁行

update blog set title='xx' where title='yy'

如上,更新的时候没有走索引,那就锁整表。

这里有一个问题?那上面说的悲观锁的for update 是属于行锁还是表锁呢?
上面这个问题本身就是有问题的,因为锁的悲观与乐观和锁的行与表是两组概念,没有直接的隶属关系。

排它锁与共享锁

共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。

排他锁又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
mysql InnoDB引擎默认的修改数据语句

  • update,delete,insert都会自动给涉及到的数据加上排他锁,
  • select语句默认不会加任何锁类型,
  • 对于select如果加排他锁可以使用select …for update语句,
  • 对于select加共享锁可以使用select… lock in share mode语句。

那问一个问题,假如一个线程A在update数据,(在线程A还没有commit的时候)另一个线程B在直接select 那么可以执行么?
答案是可以。
我去,那不是读写冲突了。
是的,此时线程Bselect的数据是线程A更新执行前的老数据。

参考资料

https://www.jianshu.com/p/1dae2393270d