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

Spring数据JPA Hibernate跳过锁定行(PostgreSQL)

南门峰
2023-03-14

我试图使用Spring数据JPA(2.1)和Hibernate在PostgreSQL上执行跳过锁定查询。查询如下所示:

@Lock(LockModeType.PESSIMISTIC_WRITE)
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="-2")})
List<Obj> findByEntityAndStatus(Entity entity, Status status);

根据Spring数据JPA native query skip locked和Select for update skip locked from JPA level,它应该可以工作,但生成的查询只选择update而不跳过锁定的行。

生成的查询:

Hibernate:选择obj0_. id作为id1_5_,obj0_. name作为name6_5_,obj0_entity_identity10_5_,obj0_. status作为status8_5_对象obj0_左向外连接实体entity1_obj0_entity_id=entity1_id,其中entity1_. id=?和obj0_. status=?用于更新obj0_

我错过了什么?

共有2个答案

魏鹤轩
2023-03-14

您可以使用nativeQuery。

@Query(value = "SELECT * FROM task LIMIT 10 FOR UPDATE SKIP LOCKED", nativeQuery = true)
List<TaskEntity> fetchAllUnlocked();
左丘子平
2023-03-14

你的代码很好。你只需要记住PESSIMISTIC_WRITE在Oracle和PostgreSQL 9.5中使用SELECT... FOR UPDATE SKIP LOCKED。我想你可能忘记告诉JPA,你应该使用更新版本的Postgres。所以你有两个选择:

  • tell JPA that you are using PostgreSQL Dialect which supports SKIP LOCKED:
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL10Dialect
    
    where
        subscripti0_.valid_until<=? 
    and subscripti0_.status='ACTIVE' 
    for update of subscripti0_1_ skip locked
    
    SELECT * FROM objects o WHERE o.valid_until <= :validUntil FOR UPDATE SKIP LOCKED 
    

 类似资料:
  • > 我在SpringJira上发现了关于使用@Version属性进行乐观锁定的问题。 在实现这一点之前,我如何使用典型的存储库模式来处理这个问题?

  • 读取文件已支持 windows 系统,版本号大于等于 1.3.4.1; 扩展版本大于等于 1.2.7; PECL 安装时将会提示是否开启读取功能,请键入 yes; 测试数据准备 $config = ['path' => './tests']; $excel = new \Vtiful\Kernel\Excel($config); ​ // 写入测试数据 $filePath = $excel->f

  • 我使用PostgreSQL作为作业队列。以下是检索作业并更新其状态的查询: 现在,我有几台机器,在每台机器上我有一个进程和几个线程,在每个线程上我有一个工人。同一进程中的所有工作人员共享一个连接池,通常有10-20个连接。 问题是,上面的查询会多次返回一些行! 我找不到任何理由。有人能帮忙吗? 更详细地说,我使用的是Python3和psycopg2。 更新: 我试过@a_horse_with_no

  • 我遵循grails文档,它说要做悲观锁定,我可以这样做: 所以这会锁定计划实例,直到保存完成。现在在我的例子中,我想一次锁定多个计划,如下所示: 我在默认情况下是事务性的 grails 服务中执行此操作,但上述行没有按预期工作。它不会锁定所有行,并在执行并发事务时引发。 如何在阅读时锁定多行? 有关更多信息,请参见相关问题:grails中的并发事务导致数据库陈旧状态异常

  • 我们有一个在负载均衡器下运行的web应用程序。两个用户尝试执行相同的操作,例如,两个用户同时发出相同的订单,这会创建重复的订单。 在一个事务提交之前,另一个请求正在检查是否有任何顺序。它正在创建重复的条目。两个请求都试图同时处理。 用户A 我们尝试了以下选项, 将整个管理器锁定,锁定类型为 但是这些选择都没有帮助。 请建议如何进行。 谢啦

  • 问题内容: 我在我的应用程序中做了一些重复的操作(测试),突然我收到一个奇怪的错误: 我已经重新启动服务器,但是错误仍然存​​在。可能是什么呢? 问题答案: 从Django文档中: SQLite是一个轻量级的数据库,因此不支持高级别的并发性。OperationalError:数据库已锁定错误,表明你的应用程序并发性超过sqlite在默认配置下无法处理的并发性。此错误意味着一个线程或进程在数据库连接