在java开发中,分布式锁常见的有redis分布式锁、zookeeper分布式锁 和 数据库分布式锁3种方式
redis分布式锁应用setNX
SETNX key value
将 key 的值设为 value ,当且仅当 key 不存在。
若给定的 key 已经存在,则 SETNX 不做任何动作。
SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。
返回值:
设置成功,返回 1 。
设置失败,返回 0 。
zookeeper分布式锁
zookeeper种节点的顺序性,如果是第一个创建的子节点,那么生成的子节点为/lock/node-0000000000,下一个节点则为/lock/node-0000000001,依次类推。
数据库分布式锁:
mysql数据库中主要有三种锁:
* 表锁:加锁快,不会出现死锁。但锁定粒度大,发生锁冲突的概率最高,并发度最低。
* 行锁:加锁慢,会出现死锁。但锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
* 间隙锁:开销和加锁时间界于表锁和行锁之间。它会出现死锁,锁定粒度界于表锁和行锁之间,并发度一般。
优先使用行锁,其次使用间隙锁,再其次使用表锁。
1可以通过乐观锁的方式,通过为数据库表添加一个 “version”字段来实现读取出数据时,将此版本号一同读出,之后更新时,对此版本号加1,在更新过程中,会对版本号进行比较,如果是一致的,没有发生改变,则会成功执行本次操作;如果版本号不一致,则会更新失败,实际就是个diff过程。
2也可以通过排他锁的方式,在查询语句后面增加for update,数据库会在查询过程中给数据库表增加排他锁。
3也可以通过表记录的方式,直接创建一张锁表,然后通过操作该表中的数据来实现,当我们想要获得锁的时候,就可以在该表中增加一条记录,想要释放锁的时候就删除这条记录。