数据库乐观锁与悲观锁 - Go语言中文社区

数据库乐观锁与悲观锁


为何需要乐观锁,与悲观锁这样的锁?

在这里插入图片描述

假设god同志的账上有1000元,现在有两个线程同时往他的账户上转钱。

1.A线程准备向god账户上转200,读取到账户上有1000元,事务还未提交

2.B线程准备向god账户上转100,读取到账户上有1000元,事务也还未提交

3.A线程提交了事务,god账户上变成了1200元,但是B线程此时不知道god账户上变成了1200

4.B线程随即也提交了事务,god账户上变成了1200,少了100元

因此,加锁的目的在于保障一个线程修改数据时,这个数据没有被其他的线程修改过

悲观锁与乐观锁的区别
1.在事务的基础上,悲观锁更适合短事务(长事务导致其他事务一直被阻塞,影响了系统性能),适用于查少改多

2.在事务的基础上,乐观锁更适合长事务,他的本质并不是锁,而是通过代码实现的。适用于查多改少

悲观锁的使用案例
在查的时候,对数据进行锁定。

在数据库中:for update

在Django中:select_for_update()

原生的sql:

1 开启事务

2 查询的时候加锁 —》 select * from user where id =1 for update

3 结束事务锁被释放

django中:

1 开启事务

2 在查询的时候 —》 user.objects.select_for_update().flilter(id=1).first()

3 事务结束锁被释放

乐观锁的使用案例
乐观锁的本质不是锁。他是通过代码来实现锁的。

方法:先拿到age数据,在修改的时候再次判断age是否一样。

(代码实现)目的:将这个数据中的age在原来的基础上+1

1 开启事务

2 查询的时候不做任何操作。data = user.objects.flilter(id=1).first()

3 在修在数据的时候。user.objects.filter(id=1,age=data.age).updata(age=data.age+1)

从而在我查询到我修改的时候,没有人改动过

4 如果3中的影响行数为0,证明数据被人修改。循环再次执行。如果为1,证明数据没人动过,修改成功

‘’’ 如果是可重复读,上面的乐观锁无效,必须改成read committed’’’
image
最新2020整理收集的一些高频面试题(都整理成文档),有很多干货,包含mysql,netty,spring,线程,spring cloud、jvm、源码、算法等详细讲解,也有详细的学习规划图,面试题整理等,需要获取这些内容的朋友请加Q君样:909038429
/./*欢迎加入java交流Q君样:909038429一起吹水聊天

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/xiaochengxuyuan1/article/details/113924691
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-05-16 20:35:17
  • 阅读 ( 1339 )
  • 分类:数据库

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢