某一商品库存数为100 两个人同时读取到了数量 A添加10 为110 B减20 应为90
数据上下文中A的Quantity+=10(110); B的Quantity-=20(80)
在ef框架下 提交的后台的sql语句 update quantity=A的Quantity(110)
update Quantity=B的Quantity(80) 导致库存不准确
如果在读取商品库存数时加锁 A读取完后并没有提交操作(或者提交后延迟很大) 其他用户读取这个商品或者操作其他数据时 会等待时间较长 有可能出现超时
查了许多资料 乐观锁 悲观锁 满足不了要求 有没有大神 给解答下 给个其他的思路
乐观锁 可以解决这种问题 ,B提交时会抛出错误,catch 住 重试,但是在高并发下并不是好的解决方案。在高并发下一种是直接用sql 语句 去 update ,这样就不存在 使用 ef 更新实体(分为两步,先获取,在修改)这种情况了,在更高的并发下可以考虑缓存库存数据,并保证更新操作的顺序是对的就可以了
只要你好好用回正常的EF,不要自作聪明的写SQL语句,就不会出现 Update Quantity 导致库存不准确的问题。
EF默认的设计,B语句是不能执行成功的。你非要自己写SQL让他成功,谁也拿你没办法。
有句不当的话还是要说下,高并发需要高级程序员,方案设计和编码可能都需要在你代码的基础上进行完全颠覆式的修改,
这样一说,很多人就退却了,我要的是武功秘笈,你让我练十年功?!
没有写sql语句啊 上下文的实体类 赋值减了相对应的数量 sql语句 是提交的数据库监视到 update quantiy=数量 代码中只是 new 了一个对象 字段值-=数量 没有sql语句
@塞下一群鹅: EF 正常的SQL语句是这样的
Update Quantity=110 where quantity=100
这句成功了。
Update Quantity=80 where Quantity=100 ...
这句会失败,不会出现库存不准确的问题。
如果你的SQL语句不是这样的,就是有人瞎写代码了。
这个地方你要确认下真正执行的sql是哪种
1. update tb set col=col+10 where col=100 and .....
2. update tb set col={value} where .....
如果是前者单纯针对这一个语句而言是没问题的,后面的col=100这个其实就是一个乐观锁,但如果是后面这种在代码中已经算出来了结果而且最后的sql没有col=100的限定的话那就完蛋了。
其次,这个应该是两个语句吧,如果是两个语句需要加个事务,直接一个transactionscope搞定,但需要注意在更新第一句后获取下是否真正更新成功了,如果不成功(条件不满足)则第二句就不需要执行了。
合理使用工具 —— 就像美图秀秀你拿来做图片设计。很明显存储过程是最好贴近的过程处理方式,直接作为整体过程,在过程中直接就判断标识就搞定了的事。只有合理的使用工具,没有一个工具适合所有场景,比如做游戏存数据,用ef就比较扯淡,但做业务管理等,不用ef开发效率等都是问题。
看快快快快快快快快快快快快快快快快快快
1.最简单的办法就是,加一个version字段来判断
2.这种特殊场景的可以丢到一个队列里面去,先后执行
3.使用数据库行锁
你要的答案http://www.cnblogs.com/GuZhenYin/p/7761352.html