简单说明乐观锁、悲观锁[共享锁、排它锁(行锁、表锁)]、死锁

一句话总结:
乐观锁and version=、悲观锁[共享锁lock in share mode、排它锁for update(索引行锁、表锁)]

括号表示子分类

锁的实现

1 乐观锁

通过版本字段手动实现,适用写少的场景
写多的冲突多了不断重试反倒低性能
冲突率<20%时使用,重试次数>=3

update … 
set … version=version+1
where id=#{id} and version=#{version};

体现了对比并替换(CAS操作),用版本而不是比较某个业务值是为了避免业务值不变实际是后面变回一样的值(ABA问题)

2 悲观锁

无版本字段,其他可读不可改,分两种

2.1 共享锁

其他共享锁可以SELECT进来

SELECT …  lock in share mode;

2.2 排他锁

悲观锁(共享锁和排他锁)都不能SELECT进来

SELECT … for update;

分两种

2.2.1 行锁

使用索引

exists
SELECT … FORCE INDEX WHERE …

2.2.2 表锁

全表扫描

in

死锁

死锁条件

互斥排他
保持着排他资源又提出新资源请求
不可剥夺
环路

死锁避免

同顺序
一次性锁定
细粒度锁定(行锁)

附:线程锁的一些概念

可重入 Reentrancy

获得锁的程序因为断网等原因离开后可以重入。同一线程可以多次获得,如JAVA的synchronized,用计数器实现进入时+1,退出时-1。

重量级锁

拿不到锁马上阻塞

自旋锁

拿不到锁先空循环一会再试然后再阻塞

自适应自旋锁

根据之前的几率调整空循环次数 JDK1.6

轻量级锁

用标记,适用于少竞争的情况

偏向锁

标记ID不释放,如果另一个发现ID不是自己就升级重量级锁,适用于一般只有一个线程访问时

锁消除

锁粗化

如JVM把循环内优化为循环外

你可能感兴趣的:(简单说明乐观锁、悲观锁[共享锁、排它锁(行锁、表锁)]、死锁)