java JPA 和默认锁定模式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13568475/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 13:14:48  来源:igfitidea点击:

JPA and default locking mode

javajpatransactions

提问by Olivier J.

With JPA, we can use manually OPTIMISTICor PESSIMISTIClocking to handle entity changes in transactions.

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

I wonder how JPA handles locking if we don't specify one of these 2 modes ? No locking mode is used?

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

If we don't define an explicit locking mode, can the database integrity be lost?

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

Thanks

谢谢

采纳答案by Kohányi Róbert

I've scanned through section 3.4.4 Lock Modesof the Java Persistence API 2.0 Final Releasespecification and while I couldn't find anything specific(it doesn't state that thisis the default or anything like that) there is a footnote which says the following.

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

The lock mode type NONE may be specified as a value of lock mode arguments and also provides a default value for annotations.

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

The section is about the kinds of LockModeTypevalues available and their usages and describes which methods takes an argument of this kind and whatnot.

本节是关于LockModeType可用值的种类及其用法,并描述了哪些方法接受此类参数以及诸如此类的参数。

So, as it said LockModeType.NONEis default for annotations (JPA, annotations left and right) I guess when you use EntityManager.find(Class, Object)the default LockModeTypeis used.

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

There are some other, subtle, hints to reinforce this. Section 3.1.1 EntityManager interface.

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

The find method (provided it is invoked without a lock or invoked with LockModeType.NONE) and the getReference method are not required to be invoked within a transaction context.

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

It makes sense. For example if you use MySQL as your database and your database engine of choice is InnoDB then (by default) your tables will use REPEATABLE READ, if you use some other RDBMS or other database engines this could change.

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

Right now I'm not exactly sure that isolation levels has anything to do with JPA lock modes (although it seems that way), but my point is that different database systems differ so JPA can't decide for you (at least according to the specification) what lock mode to use by default, so it'll use LockModeType.NONEif you don't instruct it otherwise.

现在我不确定隔离级别是否与 JPA 锁定模式有关(尽管看起来是这样),但我的观点是不同的数据库系统不同,因此 JPA 无法为您决定(至少根据规范)默认情况下使用哪种锁定模式,因此LockModeType.NONE如果您不以其他方式指示它,它将使用它。

I've also found an article regarding isolation levels and lock modes, you might want to read it.

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

Oh, and to answer your last question.

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

If we don't define an explicit locking mode, can the database integrity be lost?

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

It depends, but if you have concurrent transactions then the answer is probably yes.

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

回答by Barry Zhong

Due to JPA 2.1 FR

由于 JPA 2.1 FR

3.2 Version Attributes

The Version field or property is used by the persistence provider to perform optimistic locking. It is accessed and/or set by the persistence provider in the course of performing lifecycle operations on the entity instance. An entity is automatically enabled for optimistic locking if it has a property or field mapped with a Version mapping.

3.2 版本属性

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

So if the entity is a versioned object, such as a @Version has been specified, then the default persistence provider will perform optimistic locking.

所以如果实体是一个版本化的对象,比如已经指定了@Version,那么默认的持久化提供者将执行乐观锁。

回答by Mehmet Erdemsoy

In the specification persistence_2.0, page 89:

在规范 persistence_2.0,第 89 页中:

If a versioned object is otherwise updated or removed, then the implementation must ensure that the requirements of LockModeType.OPTIMISTIC_FORCE_INCREMENT are met, even if no explicit call to EntityManager.lock was made.

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