带有“版本”字段的乐观锁与快照隔离级别

3

我想知道这两种乐观锁方案的优缺点:

  1. 使用“版本”字段并在更新期间检测更改(例如使用Hibernate的@Version注释)

  2. 在事务中使用快照隔离级别

如果我没错的话,这两种解决方案行为相同:如果在事务期间更新了行,则会抛出错误。

谢谢


我已经添加了一个答案。如果您想要更多信息的特定方面,请告诉我。 - usr
1个回答

4
这两种方式的行为不同。使用Hibernate乐观并发,如果在此期间修改了要写入的行并进行了反向修改,则一切正常。例如+1后面跟着一个-1。 还可以修改Hibernate未检查的列。
快照隔离检查所有列并且不比较数据。任何写操作,甚至像x = x这样的空写操作都计数。
快照隔离还保证您读取的是某个时间点的快照。你没有说你打算使用哪个隔离级别来实现(1)。我假设它不是SNAPSHOT。因此,(2)很可能会给您提供hibernate无法单独提供的保证。
Hibernate乐观并发适用于分离的实体。快照隔离不能这样做,因为它需要事务来涵盖您进行的所有操作。
请注意,由于验证的是写入而不是读取,因此这两种解决方案都不可串行化。

你有关于快照隔离和版本字段+可重复读性能影响的任何想法吗?从你的回答来看,我认为最好的方法是使用版本字段,只要我们不关心幻读。你同意这个方案吗? - Quentin
1
可重复读会导致大量锁定累积。它在锁定、阻塞、开销和并发性减少方面非常接近于SERIALIZABLE。要小心。; 我不知道您的工作负载,因此无法推荐并发策略。您显然需要选择满足安全需求的策略。我无法了解这些需求。; 开销:两种策略都有开销。它们在非常不同的地方。总体而言,SI是一种很棒的工具。我看到的主要优点是它是自动化的,并且非常容易预测。如果您可以使用它,那就用吧。它在几乎所有方面都比RR更好。 - usr
我可以更好地回答那些更具体的问题。我的回答含糊不清是由于问题的广泛性。 - usr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接