数据库 锁机制

https://www.cnblogs.com/houan/p/6253293.html

https://blog.csdn.net/samjustin1/article/details/52210125

一、为什么需要了解锁

1.1 死锁问题

1.2 并发问题导致的不正确数据的读取和存储,破坏数据一致性的

  • 丢失更新
  • 脏读
  • 不可重复读
  • 幻读

二、锁的分类

2.1 数据库维度

  • 共享锁(Shared lock,读锁):用于不更改或不更新数据的操作(只读操作)。共享锁允许并发事务读取同一个资源,数据资源上存在共享锁时,任何其他事务不允许修改数据
  • 排他锁(Exclusive lock,写锁): 用于数据修改,确保不会同时多重更新同一数据。资源上存在排他锁时,其他任何事务不允许给资源上锁,当资源上有其他锁时,也无法对其加上排它锁
  • 更新锁(Update lock):
    1. 用于可更新的资源中,防止多个会话在读取、锁定以及随后可能进行的资源更新时发生的死锁问题。
    2. 通常形式的死锁:一般一个更新模式由一个事务组成,此事务读取记录,获取资源的共享锁,然后修改行,此操作要求锁转换为排它锁。如果两个事务同时获得了资源上的共享锁,然后试图同时更新数据,则一个事务尝试将锁转换为排它锁。由于一个事务的排它锁与另一事务的共享锁的不兼容,从共享锁到排它锁的转换必须要等待一段时间,发送锁等待。而第二个事务同时也试图获取排它锁进行更新。由于两个事务都要转化为排它锁,并且每个事务都要等待另一个事务释放掉共享锁,因此发生死锁
    3. 更新锁一次只有一个事务可以获取资源的更新锁。如果事务修改资源,那么更新锁转化为排它锁,否则转化为共享锁。当资源上存在更新锁时,允许资源被读取(即更新锁与共享锁兼容),但不允许资源被修改
    4. 一般来说,在执行UPDATE操作时,SQL SERVER会使用到更新锁而不是依次加上共享锁和排它锁,已经回避了这种通常形式的死锁,更新锁与意向锁相互兼容

    [更新锁的意思是:“我现在只想读,你们别人也可以读,但我将来可能会做更新操作,我已经获取了从共享锁(用来读)到排他锁(用来更新)的资格”。一个事物只能有一个更新锁获此资格。]

2.2 程序员思想维度

  • 悲观锁:
  1. 悲观并发控制(又名“悲观锁”,Pessimistic Concurrency Control,缩写“PCC”)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作都某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。悲观锁的实现,往往依靠数据库提供的锁机制。悲观并发控制主要用于数据争用激烈的环境,以及发生并发冲突时使用锁保护数据的成本要低于回滚事务的成本的环境中
  2.  悲观并发控制实际上是“先取锁再访问”的保守策略,为数据处理的安全提供了保证。但是在效率方面,处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会;另外,在只读型事务处理中由于不会产生冲突,也没必要使用锁,这样做只能增加系统负载;还有会降低了并行性,一个事务如果锁定了某行数据,其他事务就必须等待该事务处理完才可以处理那行数

  • 乐观锁:
  1. 乐观并发控制(又名“乐观锁”,Optimistic Concurrency Control,缩写“OCC”)是一种并发控制的方法。它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。
  2. 乐观并发控制相信事务之间的数据竞争(data race)的概率是比较小的,因此尽可能直接做下去,直到提交的时候才去锁定,所以不会主动产生任何锁和死锁。但是在并发量高的情况下,可能导致某次数据修改多次重试,影响单次成功操作的时间。
  3. 数据版本实现乐观锁:实现数据版本有两种方式,第一种是使用版本号,第二种是使用时间戳。使用版本号时,可以在数据初始化时指定一个版本号,每次对数据的更新操作都对版本号执行+1操作。并判断当前版本号是不是该数据的最新的版本号。

猜你喜欢

转载自blog.csdn.net/qq_35546040/article/details/80327744