当前位置: 首页 > 知识库问答 >
问题:

如何在spring数据jpa查询中指定@lock超时?

杜君浩
2023-03-14

如何为查询指定@lock超时?我使用的是Oracle11g,我希望可以使用类似'Select id from table where id=?1 for update wait5'这样的东西。

@Lock(LockModeType.PESSIMISTIC_WRITE)
Stock findById(String id);

共有1个答案

张和豫
2023-03-14

若要悲观地锁定实体,请将锁定模式设置为pessimistic_readpessimistic_writepessimistic_force_increment

如果无法获得悲观锁,但锁定失败没有导致事务回滚,则抛出LockTimeoutException

悲观锁定超时

如果在多个地方设置了javax.persistence.lock.timeout,则将按照以下顺序确定该值:

  1. EntityManager查询方法之一的参数
  2. @namedquery批注中的设置。
  3. Persistence.CreateEntityManagerFactory方法的参数。
  4. persistence.xml部署描述符中的值。

从Spring Data JPA的1.6版开始,CRUD方法就支持@lock(事实上,已经有一个里程碑可用)。详见此票。

对于该版本,您只需声明以下内容:

interface WidgetRepository extends Repository<Widget, Long> {

  @Lock(LockModeType.PESSIMISTIC_WRITE)
  Widget findOne(Long id);
}

这将导致备份存储库代理的CRUD实现部分将配置的LockModeType应用于EntityManager上的find(…)调用。

TransactionSynchronizationManager.bindResource(method, lockMode == null ? NULL : lockMode);

您可以创建一些静态锁管理器,它有一个ThreadLocal 成员变量,然后在每个存储库中的每个方法周围包装一个方面,它调用bindResource并在ThreadLocal中设置锁模式。这将允许您在每个线程的基础上设置锁定模式。然后,您可以创建自己的@methodlockmode注释,该注释将方法包装在一个方面中,该方面在运行方法之前设置线程特定的锁定模式,并在运行方法之后将其清除。

  1. 使用Spring Data JPA查找实体时,如何启用lockmodetype.pessimistic_write?
  2. 如何向Spring Data JPA添加自定义方法
  3. Spring Data Passivistic Lock Timout with Postgres
  4. JPA查询API

实体对象可以通过lock方法显式锁定:

em.lock(employee, LockModeType.PESSIMISTIC_WRITE);

如果调用lock时没有活动事务,则会引发TransactionRequiredException(因为显式锁定需要活动事务)。

如果无法授予请求的悲观锁,则引发LockTimeoutException:

  • 如果另一个用户(由另一个EntityManager实例表示)当前持有该数据库对象上的pessimistic_write锁,则pessimistic_read锁请求将失败。
  • 如果其他用户当前持有该数据库对象的pessimistic_write锁或pessimistic_read锁,则pessimistic_write锁请求将失败。

可以在以下范围(从全局到本地)中设置查询提示:

对于整个持久性单元-使用persistence.xml属性:

<properties>
   <property name="javax.persistence.query.timeout" value="3000"/>
</properties>

对于EntityManagerFactory-使用createEntityManagerFacotory方法:

Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 4000);
EntityManagerFactory emf =
  Persistence.createEntityManagerFactory("pu", properties);
Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 5000);
EntityManager em = emf.createEntityManager(properties);
em.setProperty("javax.persistence.query.timeout", 6000);
@NamedQuery(name="Country.findAll", query="SELECT c FROM Country c",
    hints={@QueryHint(name="javax.persistence.query.timeout", value="7000")})

对于特定的查询执行-使用sethint方法(在执行查询之前):

query.setHint("javax.persistence.query.timeout", 8000);
  1. 在JPA中锁定
  2. 悲观锁定超时
 类似资料:
  • 我有3个实体在我的数据库。实体A具有主密钥PK-A,实体B具有主密钥PK-B,实体C具有主密钥PK-C。 实体A与实体B具有1对多关系,实体B与实体C具有1对多关系 我想在Spring Data JPA中基于PK-A(实际上是实体B中的外键)查询实体C。有可能吗? 但这行不通。还有什么建议我可以试试吗?

  • 在我的数据库中,我有一个具有以下属性的表“CITA”:id,fecha\u hora,description,id\u empleado,id\u cliente。 我还有一个Spring JPA存储库: 我需要这个查询: 我的问题是我不知道我应该把它放在哪里来还给我像地图这样的东西 因为它不起作用: 编辑 如果我试图从我的REST控制器调用estadistic as(),我有一个错误。 这是我的

  • 使用Spring Boot应用程序。我有一个类UserService,我在其中创建了一个动态查询,根据请求参数具有多个or条件: 我有UserRepository接口,我需要执行这个查询。到目前为止,我使用了findById等JPA函数或@Query(“从事件中选择id”)。 如何将此查询从服务类传递到存储库并执行它?

  • 谁能告诉我@Query注释将支持数据库独立性查询机制 例子: 如果我写这个查询,它会支持所有的数据库,如Mysql、oracle、postgres。 我在spring data jpa参考文档站点中发现了类似的内容 这意味着如果我编写nativeQuery=true,它将被视为本机查询,如果不编写,它将表现为Spring data jpa特定查询,或者它将如何表现请澄清。

  • 我有一个实体 及其存储库 注意:如您所见,intValue不是entity类的成员变量。

  • 我正在使用mssql和spring数据JPA,我想通过使用自定义查询注释将新记录插入到表中。 它的给定错误, 原因:组织。冬眠hql。内部的ast。QuerySyntaxException:应为打开,在第1行第23列[插入到客户值(?1,?2)]附近找到“值” 我也试过下面,同样的错误。