下面的所有例子都以一个下面这表为例
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';
如上,更新的时候没有走索引,那就锁整表(此时,在另一个线程里如果想更新title='ppp’的数据也是不生效的,因为这边更新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.toymoban.com/news/detail-421768.html
参考资料
https://www.jianshu.com/p/1dae2393270d文章来源地址https://www.toymoban.com/news/detail-421768.html
到了这里,关于mysql锁的相关知识的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!