Select 用于从 JPA 级别锁定的更新跳过
Select for update skip locked from JPA level
在我的应用程序 - Oracle with JPA (EclipseLink) 中,我使用以下表达式锁定某些表中的记录子集:
select * from MY_TABLE where MY_CONDITIONS for update skip locked
我 运行 它贯穿本机查询,但我必须为所有必需的实体编写该查询。
有什么方法可以使用纯 JPA 跳过锁定的记录吗?我可以实施自己的锁定策略吗?
我不介意更换 JPA 提供程序,但我想使用 JPA API。
Oracle 不提供读锁,因为它不需要;撤消日志使它变得不必要。所以,SELECT...FOR UPDATE 实际上只是 Oracle 的 WRITE 锁。
使用 JPA,您想将 LockModeType 设置为 PESSIMISTIC_WRITE。
Hibernate 提供 UPGRADE_SKIPLOCKED 锁定模式。
使用 JPA 和 Hibernate,根据 Hibernate LockMode documentation, you have to combine the PESSIMISTIC_WRITE JPA LockModeType:
生成 "SKIP_LOCKED"
entityManager.find(Department.class, 1, LockModeType.PESSIMISTIC_WRITE);
和锁定超时设置,例如 persistence.xml 中的持久性单元:
<properties>
<property name="javax.persistence.query.timeout" value="-2"/>
</properties>
(注意复杂查询也可以配置此LockMode)
SKIP LOCKED 不属于 ANSI SQL。以下某些 RDBMS 将此作为特定功能提供:
所以对于纯 JPA,不可能在查询中指定 "SKIP LOCKED"。
实际上,如 LockModeType 中所述,JPA 2.1 仅支持以下内容:
- NONE
- 乐观
- OPTIMISTIC_FORCE_INCREMENT
- PESSIMISTIC_FORCE_INCREMENT
- PESSIMISTIC_READ
- PESSIMISTIC_WRITE
- 阅读
- 写入
但是,要在您的查询中启用 SKIP LOCKED,您可以使用这些替代方法:
- 使用特定的 JPA 实现功能,例如 Hibernate LockMode,由于 PESSIMISTIC_WRITE 的组合,它允许通过 JPA 查询指定 SKIP LOCKED LockModeType Lock Timeout 具体设置如上所述
- 像您一样创建本机 SQL 查询
我知道这个 post 有点旧,但是为了记录,正如接受的答案所述,"javax.persistence.lock.timeout" (org.hibernate.cfg.AvailableSettings#JPA_LOCK_TIMEOUT
) 设置为“-2”(org.hibernate.LockOptions#SKIP_LOCKED
) 与 Hibernate 结果 "SKIP LOCKED"。但是,这可以在 运行 时完成,而无需设置任何全局设置。
从 2.0 JPA 开始 allows to pass hints 一直如此
entityManager.find(MyType.class, id, LockModeType.PESSIMISTIC_WRITE, new HashMap<String, Object>() {{
put("javax.persistence.lock.timeout", "-2");
}});
对于springJpaRepository,可以这样使用:
String SKIP_LOCKED = "-2";
@QueryHints(@QueryHint(name = AvailableSettings.JPA_LOCK_TIMEOUT, value = SKIP_LOCKED))
@Lock(LockModeType.PESSIMISTIC_WRITE)
List<YourEntity> fooBar();
在 Oracle 上运行良好,不确定其他
在我的应用程序 - Oracle with JPA (EclipseLink) 中,我使用以下表达式锁定某些表中的记录子集:
select * from MY_TABLE where MY_CONDITIONS for update skip locked
我 运行 它贯穿本机查询,但我必须为所有必需的实体编写该查询。
有什么方法可以使用纯 JPA 跳过锁定的记录吗?我可以实施自己的锁定策略吗?
我不介意更换 JPA 提供程序,但我想使用 JPA API。
Oracle 不提供读锁,因为它不需要;撤消日志使它变得不必要。所以,SELECT...FOR UPDATE 实际上只是 Oracle 的 WRITE 锁。
使用 JPA,您想将 LockModeType 设置为 PESSIMISTIC_WRITE。
Hibernate 提供 UPGRADE_SKIPLOCKED 锁定模式。
使用 JPA 和 Hibernate,根据 Hibernate LockMode documentation, you have to combine the PESSIMISTIC_WRITE JPA LockModeType:
生成 "SKIP_LOCKED"entityManager.find(Department.class, 1, LockModeType.PESSIMISTIC_WRITE);
和锁定超时设置,例如 persistence.xml 中的持久性单元:
<properties>
<property name="javax.persistence.query.timeout" value="-2"/>
</properties>
(注意复杂查询也可以配置此LockMode)
SKIP LOCKED 不属于 ANSI SQL。以下某些 RDBMS 将此作为特定功能提供:
所以对于纯 JPA,不可能在查询中指定 "SKIP LOCKED"。 实际上,如 LockModeType 中所述,JPA 2.1 仅支持以下内容:
- NONE
- 乐观
- OPTIMISTIC_FORCE_INCREMENT
- PESSIMISTIC_FORCE_INCREMENT
- PESSIMISTIC_READ
- PESSIMISTIC_WRITE
- 阅读
- 写入
但是,要在您的查询中启用 SKIP LOCKED,您可以使用这些替代方法:
- 使用特定的 JPA 实现功能,例如 Hibernate LockMode,由于 PESSIMISTIC_WRITE 的组合,它允许通过 JPA 查询指定 SKIP LOCKED LockModeType Lock Timeout 具体设置如上所述
- 像您一样创建本机 SQL 查询
我知道这个 post 有点旧,但是为了记录,正如接受的答案所述,"javax.persistence.lock.timeout" (org.hibernate.cfg.AvailableSettings#JPA_LOCK_TIMEOUT
) 设置为“-2”(org.hibernate.LockOptions#SKIP_LOCKED
) 与 Hibernate 结果 "SKIP LOCKED"。但是,这可以在 运行 时完成,而无需设置任何全局设置。
从 2.0 JPA 开始 allows to pass hints 一直如此
entityManager.find(MyType.class, id, LockModeType.PESSIMISTIC_WRITE, new HashMap<String, Object>() {{
put("javax.persistence.lock.timeout", "-2");
}});
对于springJpaRepository,可以这样使用:
String SKIP_LOCKED = "-2";
@QueryHints(@QueryHint(name = AvailableSettings.JPA_LOCK_TIMEOUT, value = SKIP_LOCKED))
@Lock(LockModeType.PESSIMISTIC_WRITE)
List<YourEntity> fooBar();
在 Oracle 上运行良好,不确定其他