数据库隔离级别 悲观琐,乐观锁

本文探讨了在非Serializable隔离级别下出现的更新丢失问题,并详细介绍了两种解决方法:悲观锁和乐观锁。悲观锁通过数据库层面的for update锁定机制确保数据一致性,而乐观锁则依赖版本号和CAS算法实现冲突检测。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于隔离级别这篇说的最好了:[url]http://singo107.iteye.com/blog/1175084[/url]


我补充的是更新丢失的问题。
当然 所有事务串行情况下不可能出现这个问题。
但就像文章说的 Serializable级别几乎在实际项目中是不会出现的。

先看更新丢失的场景吧:其实都不用绝对并发就会出现。

比如同一件商品被在2个请求中分别被购买1件, 请求A取出库存是100,大于等于1,那么可以购买。请求B比请求A慢2秒进来,取出库存也是100,OK,也可以购买。
这时候经过大量的业务处理,比如花费了3秒钟,A把商品库存修改为 100-1 =99;
2秒后紧接着B也会执行完业务逻辑,修改库存也是把读到的库存减去1 100-1 =99。

很显然,正确结果应该是98。这就所谓的更新丢失,先更新的没起到作用(如果2次是修改不同字段,就是丢失)。


在非 Serializable 级别下,怎么解决这个问题呢。


悲观锁方法:悲观锁是数据库实现的,查询的时候在sql语句最后加上 for update关键字,会在读之后把这条锁住。其他事务甚至都不能读!其实相当于还是把事务弄成串行。。。很显然高并发下完全不可行。

乐观锁方法:乐观锁其实由程序来实现,每条记录修改后都带一条版本号,假如请求A读取到100的版本号是1,那么修改的时候检查下,当前版本号和读的版本号是不是一致,一致的话,可以修改。 修改成99后立即把该条记录的版本号变成2。

这时候B请求呢,发送修改命令的时候,提供的版本号还是1,和当前版本号2对不上,不允许修改。。。

用的CAS方法,其实这个方法极其常用,比如svn。。。
[b]乐观锁的缺点。它不是数据库级别的,假使有另外一套程序也来操作这个数据,就管不了。[/b]


为什么第一种方法叫悲观锁呢,因为他认为,每一次读数据都可会冲突,但是这终究还是少数情况。所以说他的世界观悲观。。。乐观锁就乐观多了。

恩,就补充这么多。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值