乐观锁和悲观锁
- 乐观锁:类似Java中的CAS算法,每次读数据的时候都认为别人不会修改数据,所以不会上锁,只有在更新的时候去判断数据是否被修改过,一般都会使用版本号机制实现。
- 悲观锁:类似Java中的synchronized和lock锁,每次都认为别人会修改数据,所以每次读数据时都会上锁,这样别人想修改数据时就会被阻塞。MySQL中的行锁,表锁等都是悲观锁。
共享锁和排他锁
在InnoDB存储引擎中两种行级锁:
- 共享锁(S lock):允许事务读一行数据
- 排他锁(X lock); 允许事务更新或删除一行数据
如果一个事务已经获取行的S锁,那么其它事务也可以获取该行的S锁,因为S锁并没有改变数据。但是其他事务不能获取该行的X锁,必须等S锁释放后才能获取X锁。
下面展示了S锁和X锁的兼容性(可见只有S锁与S锁是兼容的,也就是说一个行可以被多个事务同时拥有S锁):
S锁 | X锁 | |
---|---|---|
S锁 | 兼容 | 不兼容 |
X锁 | 不兼容 | 不兼容 |
先来建一张表用于后面的示例:
Create Table: CREATE TABLE `test` (
`id` int(1) NOT NULL AUTO_INCREMENT,
`name` varchar(8) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
然后插入两条数据:
insert into test(name) values("小熊"), ("小杰");
在MySQL中可以显示上锁,FOR UPDATE用于X锁,LOCK IN SHARE MODE 用于S锁。
共享锁
上面已经说了,共享锁就是读锁,也就是读数据的时候上锁,因为读数据不会改变数据,所以允许多个事务同时拥有读锁,下面来验证一下:
第一个事务: