25

使用 JPA,我们可以使用手动OPTIMISTICPESSIMISTIC锁定来处理事务中的实体更改。

如果我们不指定这两种模式之一,我想知道 JPA 如何处理锁定?没有使用锁定模式?

如果我们不定义显式锁定模式,数据库完整性会丢失吗?

谢谢

4

3 回答 3

18

我浏览了Java Persistence API 2.0 Final Release规范的第 3.4.4 节锁定模式,虽然我找不到任何具体的东西(它没有说明是默认设置或类似的东西),但有一个脚注说如下。

锁定模式类型 NONE 可以指定为锁定模式参数的值,并且还为注释提供默认值。

该部分是关于LockModeType可用值的种类及其用法,并描述了哪些方法采用这种类型的参数和诸如此类的参数。

所以,正如它所说LockModeType.NONE的是注释的默认值(JPA,注释左右)我猜当你使用EntityManager.find(Class, Object)默认值时LockModeType

还有一些其他微妙的提示可以加强这一点。第 3.1.1 节EntityManager 接口

find 方法(假设它在没有锁的情况下调用或使用 LockModeType.NONE 调用)和 getReference 方法不需要在事务上下文中调用。

这说得通。例如,如果您使用 MySQL 作为数据库并且您选择的数据库引擎是 InnoDB,那么(默认情况下)您的表将使用REPEATABLE READ,如果您使用其他一些 RDBMS 或其他数据库引擎,这可能会改变。

现在我不确定隔离级别与 JPA 锁定模式有什么关系(尽管看起来是这样),但我的观点是不同的数据库系统不同,所以 JPA 无法为你做出决定(至少根据规范)默认使用什么锁定模式,所以LockModeType.NONE如果你不指示它会使用它。

我还找到了一篇关于隔离级别和锁定模式的文章,您可能想阅读它。

哦,回答你的最后一个问题。

如果我们不定义显式锁定模式,数据库完整性会丢失吗?

取决于,但如果您有并发事务,那么答案可能是肯定的。

于 2012-11-26T17:07:49.917 回答
15

由于 JPA 2.1 FR

3.2 版本属性

持久性提供程序使用 Version 字段或属性来执行乐观锁定。它由持久性提供者在对实体实例执行生命周期操作的过程中访问和/或设置。如果实体具有使用版本映射映射的属性或字段,则会自动启用乐观锁定。

因此,如果实体是版本化对象,例如已指定 @Version,则默认持久性提供程序将执行乐观锁定。

于 2013-11-09T05:23:37.733 回答
6

在规范 persistence_2.0,第 89 页:

如果版本化对象以其他方式更新或删除,则实现必须确保满足 LockModeType.OPTIMISTIC_FORCE_INCREMENT 的要求,即使没有对 EntityManager.lock 进行显式调用。

于 2014-08-20T09:11:28.750 回答