mysql中的共享锁和悲观锁以及共享锁和排他锁

这段情,曾夏了夏天,后来却也冬了冬天

悲观锁

操作前假设一切操作都可能发现并发冲突,所以采取悲观态度。通过加锁,屏蔽一切可能违反数据完整性的操作
比方

1
2
select * from table for update;  --就是表锁
select * from table where x = 1 for update; --就是行锁

当使用for update后,其它会话还是可以执行select操作,但无法执行select xx for update操作,只有当前会话commit后,其它for update操作才会被执行。

for update仅适用于InnoDB,且必须在事务块(BEGIN/COMMIT)中才能生效

1
2
3
4
BEGIN;
SELECT * FROM test FOR UPDATE;
SLEEP(20);
COMMIT;

乐观锁

假定操作很少发生冲突,一般对于读多写少的情况。只在提交操作时检查是否违反数据完整性, 乐观锁不能解决脏读的问题。
可以通过版本号是否比上个版本号或者时间戳来实现, 也或者检查通过检查某个字段来实现;
对于冲突检测后的处理,需要业务逻辑去处理。

排它锁

当数据对象被加上排它锁时,其他的事务不能对它读取和修改。

1
2
3
BEGIN;
SELECT * FROM test FOR UPDATE;
COMMIT;

共享锁

加了共享锁的数据对象可以被其他事务读取,但不能修改。

1
SELECT * from city where id = "1"  lock in share mode;