如何处理锁(JPA)?

Posted

技术标签:

【中文标题】如何处理锁(JPA)?【英文标题】:How to deal with locks (JPA)? 【发布时间】:2011-11-04 08:51:34 【问题描述】:

根据Java Persistent/Locking wikibooks*,处理锁的最好方法是向用户报告乐观锁错误/异常。

问题在于它不可扩展。假设我有很多用户可能会通过相同的操作导致锁定。用户不关心锁错误信息。

简而言之:

最好的方法是禁用所有锁? 最好的方法是向用户报告错误锁定消息?但是用户必须重试他的操作,直到它起作用! 最好的方法是重试事务直到没有锁?

*

处理乐观锁异常

不幸的是,程序员常常为了自己的利益而过于聪明。使用乐观锁定时出现的第一个问题是发生 OptimisticLockException 时该怎么办。友邻超级程序员的典型反应,是自动处理异常。他们只会创建一个新事务,刷新对象以重置其版本,并将数据合并回对象并重新提交。 Presto 问题解决了吗?

这实际上首先破坏了锁定的全部意义。如果这是您想要的,您也可以使用无锁定。不幸的是,OptimisticLockException 很少会被自动处理,你真的需要就这个问题来打扰用户。您应该向用户报告冲突,或者说“抱歉,但发生了编辑冲突,他们将不得不重做他们的工作”,或者在最好的情况下,刷新对象并向用户呈现当前数据并他们提交的数据,并在适当的情况下帮助他们合并两者。

一些自动合并工具会比较数据的两个冲突版本,如果没有一个单独的字段发生冲突,那么数据将在没有用户帮助的情况下自动合并。这是大多数软件版本控制系统所做的。不幸的是,用户通常比程序更能决定什么时候发生冲突,仅仅因为 .java 文件的两个版本没有更改同一行代码并不意味着没有冲突,第一个用户可能已经删除了一个其他用户添加了一个方法来引用的方法,以及其他几个可能导致通常夜间构建经常中断的问题。

【问题讨论】:

How to disable the lock system of JPA? 的可能副本,来自同一作者。 我会说它们不是重复的,因为一个问如何禁用,另一个问带锁的策略。 【参考方案1】:

用户会关心消息,因为他想做一些修改,而修改还没有进行。因此,他将刷新页面以查看数据的新状态,并重新进行修改,或者在新状态下决定不再进行修改。

如果两个用户同时修改一个实体,如果最后一个修改获胜,不管修改是什么,这是否有问题?如果是问题,则使用乐观锁定,并在出现问题时通知您的用户。没有办法解决它。

如果没问题,就不要使用乐观锁。最后一次修改,如果它不破坏数据库中的约束,将永远获胜。但是让并发用户修改相同的数据将总是导致异常(例如,因为某些用户可能会在其他用户提交对同一实体的修改之前删除一个实体)。

重试不是一种选择:

要么再次失败,因为无法进行修改 或者它会成功,但首先会破坏乐观锁定这一点。

您的问题可以用汽车类比来解释。假设您选择购买带有限速器的汽车,以确保您不会超速。现在你问:但我不在乎速度限制。我不应该总是禁用限速器吗?你可以,但如果你被警察抓住了,不要感到惊讶。

【讨论】:

感谢您的精彩解释

以上是关于如何处理锁(JPA)?的主要内容,如果未能解决你的问题,请参考以下文章

JPA 2.0 如何处理死锁(Eclipselink JPA2.0 MySQL)

如何处理指向通用接口的指针的 JPA 注释

如何处理 JPA @OneToOne 映射中的“孤立”行

如何处理来自catch块的spring jpa @transactional和新插入[重复]

您如何处理 Spring Data JPA 中 ID 数组的批量删除?

JPA中,在调用persist()时,数据库自动增长的主键如何处理