【发布时间】:2012-11-14 03:27:10
【问题描述】:
使用 JPA,我们可以手动使用 OPTIMISTIC 或 PESSIMISTIC 锁定来处理事务中的实体更改。
我想知道如果我们不指定这两种模式中的一种,JPA 如何处理锁定? 没有使用锁定模式?
如果我们不定义显式锁定模式,会不会丢失数据库完整性?
谢谢
【问题讨论】:
标签: java jpa transactions
使用 JPA,我们可以手动使用 OPTIMISTIC 或 PESSIMISTIC 锁定来处理事务中的实体更改。
我想知道如果我们不指定这两种模式中的一种,JPA 如何处理锁定? 没有使用锁定模式?
如果我们不定义显式锁定模式,会不会丢失数据库完整性?
谢谢
【问题讨论】:
标签: java jpa transactions
我浏览了Java Persistence API 2.0 Final Release 规范的第 3.4.4 节 锁定模式,虽然我找不到任何特定的内容(它没有说明this 是默认值或类似的东西)有一个脚注说明以下内容。
锁定模式类型 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。
我也找到了an article regarding isolation levels and lock modes,你可能想看看。
哦,回答你的最后一个问题。
如果我们不定义显式锁定模式,数据库可以 完整性丢失?
它取决于,但如果您有并发事务,那么答案可能是是。
【讨论】:
由于 JPA 2.1 FR
3.2 版本属性
持久化提供程序使用版本字段或属性来执行乐观锁定。它由持久性提供者在对实体实例执行生命周期操作的过程中访问和/或设置。 如果实体具有使用版本映射映射的属性或字段,则会自动启用乐观锁定。
所以如果实体是一个版本化的对象,比如已经指定了@Version,那么默认的持久化提供者将执行乐观锁定。
【讨论】:
在规范 persistence_2.0,第 89 页:
如果版本化对象以其他方式更新或删除,则实现必须确保 满足 LockModeType.OPTIMISTIC_FORCE_INCREMENT 的要求,即使没有明确的 调用了 EntityManager.lock。
【讨论】: