数据库事务和锁的关联以及分布式锁的实现

知识共享许可协议 版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

目录

 

一:事务和锁的关联

1.事务和锁的联系

2.什么是锁

3.分布式锁的特性

4.分布式锁解决的问题

二:基于数据库锁的实现方式之一:唯一主键乐观锁

1.实现思路或者原理

2.不足点:

3.解决不足的方案

三:基于表字段版本号

1.思路

2.优缺点

四:基于排它锁

  思路

五:基于Redis的锁

 1.setindex()和expire()实现的锁

2.setindex()和get()以及getset()实现的锁

3.其他方案


一:事务和锁的关联

1.事务和锁的联系

   在上一章谈到过数据库事物的实现思路(单库单表事物到分布式事物一键解读),我们这里跳出事物实来谈,事物保证了了单

个(或者说某一个瞬间)用户在数据库一系列顺序的操作的一致性。如下:可以理解为垂直层面的一系列操作。

   而锁视为保证在某一个瞬间只能有一个用户操作,而其他用户只能等待,而这种情况产生的前提就是,有一张表关联了其他许

多张表,且其他表的操作都会影响该表。如图

2.什么是锁

  (1)锁产生的背景:在高并发的情况,当一个线程或者方法被同时调用时,我们需要方法或者线程的调用有个顺序性,否则会

                                        导致结果或者数据不一一对应。

   (2)锁的特性:当一个线程或者方法的调用需要一个顺序性,且在某一个时刻只能有一个执行。锁是为了实现同步。

3.分布式锁的特性

 (1)可重入锁:锁不能产生死锁

 (2)竞争锁:锁执行等级的是否一致

  (3)阻塞锁:锁的竞争机制

  (4)高可用的获取/释放锁的方法:锁是个很消耗资源的,所以在锁的获取/释放性能要好

4.分布式锁解决的问题

   简而言之:保证数据的强一致性。在上章中(参照上诉地址)提到在分布式中大多数场景中CAP理论都是满足AP(即一致性

和容错性,至于原因也讨论过)而达到结果的强一致性,那么势必会牺牲一部分一致性,这时候锁会在很大程度上保证一致性。

但是,在大多数的互联网场景中,AP能满足结果的强一致性而且锁真的是一个很耗资源的东西,因此,我们对于锁的使用一定要

多加考虑。

二:基于数据库锁的实现方式之一:唯一主键乐观锁

  准确来说这是一种设计思路而不是一种实现方法。基于数据库锁的思路都是基于数据库的事物的隔离级别。

1.实现思路或者原理

          基于主键唯一的特性。当多个用户提交到数据库,使用一张主键表中的主键来判断能否执行,执行完成后,删除主键表的

主键数据,如图:

                     

2.不足点:

  (1)依赖主键表,会出现单点故障。

  (2)容易造成死锁,如果某一个操作毁掉,删除主键表出错,导致主键表中的值未删除

  (3)锁无失效时间

  (3)非公平锁:抢夺靠时间实现。

  (4)大并发的情况下,容易因为主键冲突导致锁表

3.解决不足的方案

  (1)建立主键表备份,灵活切换

  (2),(3)写个定时任务,定时清理主键表

  (4) 通过记录版本号来控制公平性

三:基于表字段版本号

1.思路

  为每一个表设置一个版本号字段,然后写一条sql语句进行每一次判断。

2.优缺点

  基于mvcc机制,但是表入侵过大

四:基于排它锁

  思路

    在查询语句后添加一个for update来添加添加所,并且这把锁不会死锁。

五:基于Redis的锁

 1.setindex()和expire()实现的锁

  主要基于redis 的setindex()和expire()。setindex()方法是一个原子性的操作,当key不存在则key设置成功返回1,否则

返回0。expire()设置失效时间。最后执行成功删除该key。

2.setindex()和get()以及getset()实现的锁

 此法同于法1,只不过在死锁方面做了一些优化这个命令主要有两个参数 getset(key,newValue)。该方法是原子的,对 key 设置 newValue 这个值,并且返回 key 原来的旧值。

3.其他方案

 基于 REDLOCK 做分布式锁等。

猜你喜欢

转载自blog.csdn.net/qq_35755863/article/details/93597347