美文网首页
分布式锁的实现方式

分布式锁的实现方式

作者: 什么也不懂888 | 来源:发表于2019-01-23 10:18 被阅读0次

    分布式锁通常有3种实现方式,即数据库乐观锁、基于redis的分布式锁和基于zookeeper的分布式锁。

    一、基于redis的乐观锁

    选用Redis实现分布式锁原因

    Redis有很高的性能

    Redis命令对此支持较好,实现起来比较方便

    使用命令介绍

    SETNX

    SETNX key val

    当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0。

    expire

    expire key timeout

    为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。

    delete

    delete key

    删除key

    在使用Redis实现分布式锁的时候,主要就会使用到这三个命令。

    实现

    使用的是jedis来连接Redis。

    实现思想

    获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。

    获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。

    释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放。

    redisson是redis官网推荐的java语言实现分布式锁的项目。

    二、基于数据库的乐观锁

    所谓乐观锁,就是假设数据在极大多数情况下不会形成冲突,因此只有在数据提交的时候,才会对数据是否产生冲突进行检验。如果产生数据冲突了,则返回错误信息,进行相应的处理。那我们如何来实现乐观锁呢?一般采用以下方式:使用版本号(version)机制来实现,这是乐观锁最常用的实现方式。那什么是版本号呢?版本号就是为数据添加一个版本标志,通常我会为数据库中的表添加一个int类型的"version"字段。当我们将数据读出时,我们会将version字段一并读出;当数据进行更新时,会对这条数据的version值加1。当我们提交数据的时候,会判断数据库中的当前版本号和第一次取数据时的版本号是否一致,如果两个版本号相等,则更新,否则就认为数据过期,返回错误信息。

    三、基于数据库的悲观锁

    悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。悲观锁主要通过 select for update 实现。

    //0.开始事务

    begin;/begin work;/start transaction; (三者选一就可以)

    //1.查询出商品信息

    select status from t_goods where id=1 for update;

    //2.根据商品信息生成订单

    insert into t_orders (id,goods_id) values (null,1);

    //3.修改商品status为2

    update t_goods set status=2;

    //4.提交事务

    commit;/commit work;

    四、基于zookeeper的分布式锁

    1. 客户端连接zookeeper,并在/lock下创建临时的且有序的子节点,第一个客户端对应的子节点为/lock/lock-0000000000,第二个为/lock/lock-0000000001,以此类推;

    2. 客户端获取/lock下的子节点列表,判断自己创建的子节点是否为当前子节点列表中序号最小的子节点,如果是则认为获得锁,否则监听刚好在自己之前一位的子节点删除消息,获得子节点变更通知后重复此步骤直至获得锁;

    3. 执行业务代码;

    4, 完成业务流程后,删除对应的子节点释放锁。

    虽然zookeeper原生客户端暴露的API已经非常简洁了,但是实现一个分布式锁还是比较麻烦的…我们可以直接使用curator这个开源项目提供的zookeeper分布式锁实现。

    相关文章

      网友评论

          本文标题:分布式锁的实现方式

          本文链接:https://www.haomeiwen.com/subject/gzdfdqtx.html