分布式环境下的互斥实现-基于数据库(看了它,你绝对可以理解,不懂砍我)

总结下来:互斥实现>分布式环境锁,包含分布式环境锁

基于数据库数据库锁实现(这同样可以解决分布式环境下的锁问题,分布式中的基于主键也可以解决互斥问题,当然基于互斥也可以解决分布式环境下大部分的锁问题,但是为什么我们还是要用分布式锁呢?)

数据库使用悲观锁和乐观锁就可以保持互斥,那么分布式锁有个屁用!!

很多人学了后,一定会这么认为。

但是实际上,数据库锁只是对数据执行的语句,进行互斥,万一你还有操作缓存,那咋办,所以我们还是要使用分布式锁。

悲观锁

乐观锁

基于分布式环境锁实现

基于数据实库

基于redis实现

基于zookeeper实现

悲观锁:总有刁民要害郑,行锁就是悲观锁。

悲观锁有:共享锁,排它锁

共享锁:就是读锁,具有读的性质,可以让你读

排它锁:修改删除数据时,别人不能操作数据。

 

我当时看这图我也懵逼了,这是什么意思,听我娓娓道来

你可以把x理解成“写数据”,把s理解为读数据。

x锁,别人不能写也不能读(排它锁)

s锁:别人不能写,可以读(共享锁)

反正它们两个都是可以互相转换的

读锁是什么了?

就是查询select,我觉得每个select语句都是默认加了s锁的,错了不怪我,我自己认为的。

把读锁也变成排它锁

@Select("select * from t_goods where id = #{id} for update") Goods laodByIdForUpdate(Long id);

乐观锁

乐观锁:就是数据提交的时候进行检测。

最常见的手段就是,对数据库表中加字段,我记得是基于cas思想(这是什么呢?我觉得和cap有点像,我记得好像是,用预期值比较,如果是预期值就成功,不是预期值就失败,错了不怪我,我都是没工作的大四学生,投了一千份简历,我微信好友里,别个机械的,工程的都找到java工作了,我软件本科没人理,这还有天理吗!!)。

加上时间戳或者版本号,我们就以版本号为例子。(但是实际上面试的时候,谁会问那么底层,你直接说,乐观锁在数据库加上版本号或者时间戳进行比较,这样实现乐观锁,谁让举例子了!)

update account set version = version + 1 where id = #{id} and version = #{oldVersion}

第一个人获得了,版本号加一,另外一个人版本号匹配不上,后面的人都匹配不上了(他们都是老版本为0)。

没有匹配上的话,你只有在自己业务层进行判读,失败的话,自己决定该怎么办!

我没有实际用过。但是我想象的话,自己查一下数据库中的版本号,把它版本号加上去,然后再去抢,不知道这样行不行的通(上面的话,纯自己脑补的,正确性待商榷)

基于主键(唯一索引)解决互斥问题

新建一个表,每次抢到锁就insert一个数据。(sql语句就变成两个了,操作原数据,又要插入一个用来锁的表),后面的人同样也要插入,因为主键的唯一性,发现插入不了,只有等待执行完的那个进程,把记录删了才行。

比如a对数据的操作

加锁:insert into lock(id) values(1)

业务sql:update good set count = count -1 where id =1;

执行完后要释放锁:delete lock where id =1

中途要执行的人,看要拿锁拿不到(基于主键唯一性),只有等他删除记录才可以,重新拿到锁。(仿佛我们这些投了一千份简历都没工作的人,只有等他们把饭碗扔了,我们再去抢)

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值