MySQL锁机制
MySQL页面锁、乐观锁与悲观锁
#### 页面锁 页面锁是Berkeley DB存储引擎支持的一种锁粒度,当然,由于BDB引擎被Oracle收购的原因,因此MySQL5.1以后不再直接性的支持该引擎(需自己整合),因此页锁见的也比较少,大家稍微了解即可。 - 表锁:以表为粒度,锁住的是整个表数据。 - 行锁:以行为粒度,锁住的是一条数据。 - 页锁:以页为粒度,锁住的是一页数据。 #### 乐观锁 乐观锁即是无锁思想,对于这点在之前聊《并发编程系列-Unsafe与原子包》时曾详细讲到过,但悲观锁也好,乐观锁也罢,实际上仅是一种锁的思想,如下: - 乐观锁:每次执行都认为只会有自身一条线程操作,因此无需拿锁直接执行。 - 悲观锁:每次执行都认为会有其他线程一起来操作,因此每次都需要先拿锁再执行。 乐观锁与悲观锁也对应着咱们日常生活中,处理一件事情的态度,一个人性格很乐观时,做一件事情时都会把结果往好处想,而一个人性格很悲观时,处理一件事情都会做好最坏的打算。 OK~,编程中的无锁技术,或者说乐观锁机制,一般都是基于CAS思想实现的,而在MySQL中则可以通过version版本号+CAS的形式实现乐观锁,也就是在表中多设计一个version字段,然后在SQL修改时以如下形式操作: ```sql UPDATE ... SET version = version + 1 ... WHERE ... AND version = version; ``` 也就是每条修改的SQL都在修改后,对version字段加一,比如T1、T2两个事务一起并发执行时,当T2事务执行成功提交后,就会对version+1,因此事务T1的version=version这个条件就无法成立,最终会放弃执行,因为已经被其他事务修改过了。 当然,一般的乐观锁都会配合轮询重试机制,比如上述T1执行失败后,再次执行相同语句,直到成功为止。 从上述过程中不难看出,这个过程中确实未曾添加锁,因此也做到了乐观锁/无锁的概念落地,但这种形式却并不适合所有情况,比如写操作的并发较高时,就容易导致一个事务长时间一直在重试执行,从而导致客户端的响应尤为缓慢。 因此乐观锁更加适用于读大于写的业务场景,频繁写库的业务则并不适合加乐观锁。 #### 悲观锁 悲观锁的思想咱们上面已经提到了,即每次执行时都会加锁再执行,也就是在每次执行前必须获取到锁,然后才能继续往下执行,而数据库中的排他锁,就是一种典型的悲观锁类型。 在数据库中想要使用悲观锁,那也就是对一个事务加排他锁for update即可,不再重复赘述。
顶部
收展
底部
[TOC]
目录
MySQL锁机制的由来与分类
MySQL共享锁与排他锁
MySQL表锁
MySQL行锁
MySQL页面锁、乐观锁与悲观锁
MySQL死锁
MySQL锁机制的底层实现原理
相关推荐
MySQL教程
MySQL命令
MySQL索引
MySQL事务
MySQL版本特性