使用JPA,我们可以使用手动OPTIMISTIC
或PESSIMISTIC
锁定来处理事务中的实体更改。
我想知道如果我们没有指定这两种模式中的一种,JPA如何处理锁定? 没有使用锁定模式?
如果我们没有定义显式锁定模式,数据库完整性是否会丢失?
由于
答案 0 :(得分:14)
我已经扫描了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
。
我还找到了an article regarding isolation levels and lock modes,您可能想要阅读它。
哦,回答你的上一个问题。
如果我们没有定义显式锁定模式,可以使用数据库 诚信丢失了?
依赖,但如果您有并发事务,则答案可能是是。
答案 1 :(得分:11)
由于JPA 2.1 FR
3.2版本属性
持久性提供程序使用Version字段或属性来执行乐观锁定。它在实体实例上执行生命周期操作的过程中由持久性提供程序访问和/或设置。 如果实体具有使用版本映射映射的属性或字段,则会自动启用乐观锁定。
因此,如果实体是版本化对象(例如@Version),则默认持久性提供程序将执行乐观锁定。
答案 2 :(得分:5)
在规范persistence_2.0,第89页中:
如果版本化对象以其他方式更新或删除,那么实现必须确保 即使没有明确的要求,也满足LockModeType.OPTIMISTIC_FORCE_INCREMENT的要求 调用了EntityManager.lock。