乐观锁疑问
老师您好,这一节我有 3 个疑问,麻烦帮我看下我的思考对不对
相关代码
一:为什么会引出乐观锁
答:
更新行程中,需要先读后改,在并发情况下,容易发生脏读现象,所以需要进行额外的处理,如加锁
但因为在这个场景下,发生并发的概率比较小,所以我们采用了乐观锁的处理方式
二:怎样为更新行程添加乐观锁
答:
网上的文章说通过版本号控制,在读取的时候就会记下当前版本号(假设为 v1),在准备更新的时候会再读一次版本号(假设为 v2),如果 v1 == v2,就能执行更新,否则需要重试更新操作
我们项目中的 updatedAt 字段是不是就相当于上面提到的版本号,mongodb 它会把 updatedAt 字段识别为版本号标记之一吗 ❓
还有,我们的项目代码中,并没有去做版本号更新前后的比对工作,mongodb 会帮我们去做这件事吗 ❓
三:如果不使用 UpdateOne 而是 FindOneAndUpdate,是不是就不用自己去做并发控制了 ❓
正在回答
一:为什么会引出乐观锁。同学说的是一部分原因。另一方面的原因是分布式系统中,分布式事务本身非常复杂。
二:怎样为更新行程添加乐观锁。我们的updatedAt就相当于版本号。这个字段的逻辑mongodb不会帮我们做,需要我们自己去做。这里我们把UpdatedAt当做一个查询条件,只有查询到updatedAt就是我们之前获取的那个值,才可以更新。不然如果中间被别人更新过,我们带着旧的updatedAt就会查询不到,导致无法更新而出错。这就是乐观锁给我们的保护。
三:UpdateOne 而是 FindOneAndUpdate,这两个方法其实实现逻辑是一样的,并没有在并发控制上有任何区别。只是返回值不同。FindOneAndUpdate可以返回文档,而UpdateOne不能。而且我们也分析过,可以通过参数控制让它返回旧文档还是新文档。但是很重要的一点是,它并不保证Find和Update在这里的原子性。
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星