数据库层面锁
表锁
锁定一张表的全部记录
SELECT username FROM user FOR UPDATE;
行锁
锁定一行记录
SELECT username FROM user WHERE id = 1 FOR UPDATE;
所以说在 InnoDB 引擎中, 虽然默认为 ROW LOCK 但是也是在指定检索条件为主键的情况下, 否则默认 TABLE LOCK
页锁
行锁锁定一行记录, 表锁锁定一张表中全部记录, 页锁即折中锁定相邻的一组记录
共享锁
共享锁也称为读锁, 即给数据添加读锁后, 其他线程只能读取不能修改如果有修改操作会被阻塞, 进入队列
需要注意的是:
SELECT username FROM user WHERE id = 1 FOR UPDATE;
当抢锁的时候即便是普通的查询也会进入阻塞队列中
这样就可并发正常查询:
SELECT username FROM user WHERE id = 1;
排他锁
排他锁也称为写锁, 和共享锁的区别在于, 其他线程既不能读也不能修改
业务处理层面思想
乐观锁
其实并不会加锁, 只是也算是一种处理方式顾名思义, 这种情况认为不会发生并发冲突抢占资源的情况, 在数据库中通过添加 version 或时间戳的方式来控制数据的版本 1. 首先查询数据拿到 verison 2. 更新数据 3. 查询数据对比 version 是否有变 (并发冲突) 4. 没有那么更新成功 (COMMIT), 如果有那么知道有其他线程进行了 DML 操作回滚 (ROLL BACK)
悲观锁
假定会发生并发冲突, 屏蔽一切可能违反数据完整性的操作悲观锁的具体实现即数据库层面的共享锁和排它锁也只有数据库层面的锁能做到真正对数据的并发控制, 多个系统之间并不能做到良好控制