乐观锁和悲观锁

 
什么是锁?
    在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足。
 
锁的分类(oracle)
  1. 按操作划分,可分为DML锁(data locks,数据锁)、DDL锁(dictionary locks,数据字典锁)
  2. 按锁的粒度划分,可分为表级锁、行级锁、页级锁(mysql)
  3. 按锁级别划分,可分为共享锁、排他锁
  4. 按加锁方式划分,可分为自动锁、显示锁
  5. 按使用方式划分,可分为乐观锁、悲观锁
 
数据库的锁机制:
    在并发访问情况下,可能会出现脏读、不可重复读和幻读等读现象,为了应对这些问题,主流数据库都提供了锁机制,并引入了事务隔离级别的概念。
 

什么是乐观锁(Optimistic Concurrency Control)、悲观锁(Pessimistic Concurrency Control)?
 
    乐观锁:是一种并发控制的方法。它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。
    悲观锁:是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作都某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。
 
通俗定义:
    乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁。但是在更新的时候,会判断一下在此期间别人有没有去更新这个数据。
    悲观锁:先取锁再访问。每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁。当锁释放后才可以使用数据。
 

乐观锁、悲观锁的实现。
 
    乐观锁:使用数据版本(版本号、时间戳)
  1. 使用版本号时,可以在数据初始化时指定一个版本号,
  2. 每次对数据的更新操作都对版本号执行+1操作。
  3. 并判断当前版本号是不是该数据的最新的版本号。
 
    悲观锁:依靠数据库提供的锁机制
  1. 在对任意记录进行修改前,先尝试为该记录加上排他锁(exclusive locking)。
  2. 如果加锁失败,说明该记录正在被修改,那么当前查询可能要等待或者抛出异常。 具体响应方式由开发者根据实际需要决定。
  3. 如果成功加锁,那么就可以对记录做修改,事务完成后就会解锁了。
  4. 其间如果有其他对该记录做修改或加排他锁的操作,都会等待我们解锁或直接抛出异常。
 

乐观锁、悲观锁的优缺点?
 
    乐观锁的优点:
  1. 避免了长事务中的数据库加锁开销,大大提升了大并发量下的系统整体性能表现。
  2. 不会产生任何锁和死锁
    乐观锁的缺点:
  1. 需要对表的设计增加额外的字段,增加了数据库的冗余。
  2. version版本值在频繁变化,则会导致大量请求失败,影响系统的可用性。
 
    悲观锁的优点:保证数据访问的安全
    悲观锁的缺点:让数据库产生额外的开销、增加死锁的机会、降低并行性。
 

应用场景
    乐观锁:适合并发量不高,并且写操作不频繁的场景
    悲观锁:主要用于数据争用激烈的环境
 
 
参考内容:
 
 
原文地址:https://www.cnblogs.com/amusement1992/p/10096022.html