jOOQ select for update nowait 在行锁定时不会抛出

问题描述 投票:0回答:1

当将 select for update nowait 与 jooq 一起使用时,语句不会引发异常,而是继续等待行解锁。

最近我尝试在 Spring Boot 中运行的 jooq 中使用 select for update nowait ,如下所示:

 public void findByIdForUpdateNoWait(UUID id) {

        dslContext.select()
                .from(PAYMENT)
                .where(PAYMENT.ID.eq(id))
                .forUpdate()
                .noWait()
                .fetch();
    }

并编写了一个测试来检查行为:

    @Test
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    void findByIdForUpdateNoWait_fail() {

        UUID id = UUID.fromString("3d346f2f-9c44-4e8c-8479-f3eb4b46195f");
        repository.findByIdForUpdateNoWait(id);
        testTransactionProvider.runInSeparateTransaction(() -> {
            assertThrows(DataAccessException.class,()->{
                repository.findByIdForUpdateNoWait(id);
            });
        });
    }

方法 runInSeparateTransaction 是:

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void runInSeparateTransaction(Runnable test) {

        test.run();
    }

测试方法卡住了。我在日志中看到 jooq 抛出错误 DataAccessException,但该错误未到达测试方法。 这是 jooq 生成的查询(基于日志)

select "payment"."id" where "payment"."id" = '3d346f2f-9c44-4e8c-8479-f3eb4b46195f' for update nowait

在测试运行时(当另一个事务锁定行时)使用此sql直接查询数据库时:

select * from payment ipi where ipi.id = '3d346f2f-9c44-4e8c-8479-f3eb4b46195f' for update nowait;

查询按照预期抛出锁定异常。

我应该如何创建 jOOQ 查询,以便它在行被锁定时抛出,就像本机查询一样,而不是等待它们解锁?

我已阅读官方文档https://www.jooq.org/doc/latest/manual/sql-building/sql-statements/select-statement/for-update-clause/

我正在使用 jOOQ 3.14.16 和 postgres 42.6.0

java postgresql jooq
1个回答
0
投票

其实问题是我使用的

@Sql(scripts = "/sql/payment-tear-down.sql", config = @SqlConfig(transactionMode = ISOLATED), executionPhase = AFTER_TEST_METHOD)

实际上无法运行,因为事务仍然持有表上的锁,因此它挂起测试并且测试从未通过。

© www.soinside.com 2019 - 2024. All rights reserved.