简体   繁体   English

Java Spring 启动 JPA PESSIMISTIC_WRITE 未按预期工作

[英]Java Spring Boot JPA PESSIMISTIC_WRITE Not Working as Expected

I want to lock some row in my Postgres database so it cannot even be read until the process is completed.我想锁定我的 Postgres 数据库中的某些行,以便在该过程完成之前甚至无法读取它。 I read it here that it is achievable by using JPA PESSIMISTIC_WRITE, but it's not working as expected because the data is still readable.在这里读到它可以通过使用 JPA PESSIMISTIC_WRITE 来实现,但它没有按预期工作,因为数据仍然可读。

Controller Controller

I have 2 function in my controller the first one is for locking the data and the second one is test function to verify if the lock working correctly.我的 controller 中有 2 个 function 第一个用于锁定数据,第二个用于测试 function 以验证锁是否正常工作。

@GetMapping(value = "/lockdata")
public String controllerLockData() {
    serviceImplementation.lockData();
    return "sucess";
}

@GetMapping(value = "/test-lock")
public String testLock() {
    serviceImplementation.testReadUpdate();
    return "sucess";
}

serviceImplementation服务实施

@Override
@Transactional
public void lockData() {
    SomeTableEntity table = entityManager.find(SomeTableRepository.class, 42366L, LockModeType.PESSIMISTIC_WRITE);
    try {
        TimeUnit.SECONDS.sleep(60); // #1st Breakpoints, 60 second delay so I can do some testing in this 60 second
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }

    table.setColumnOne("0"); // #2nd Breakpoints
    tableRepository.save(table);
}

@Override
@Transactional
public void testLock() {
    SomeTableEntity table = tableRepository.getOne(42366L);
    table.setColumnOne("1"); //#3rd breakpoint
    tableRepository.save(table);
    int a = 1; //#4th breakpoint
}

This is how I do the testing.这就是我进行测试的方式。

  1. Set column one value to "2" (for validating later)将第一列的值设置为“2”(用于稍后验证)
  2. Call /lockdata and wait until #1st breakpoint is hit to make sure that the code is executed then continue the process in the IDE.调用 /lockdata 并等到第一个断点被命中以确保代码被执行,然后继续 IDE 中的过程。 Now I have 60 second time for doing the testing and expect the lock is already applied.现在我有 60 秒的时间进行测试,并期望锁定已经应用。
  3. Call /test-lock, #3rd breakpoint is hit immediately with the right data while I expect it shouldn't, because I expect it will wait until the lock is lifted.调用 /test-lock,#3rd 断点会立即用正确的数据命中,而我预计它不应该,因为我希望它会等到锁被解除。
  4. Continue IDE process.继续 IDE 过程。 #4th breakpoint is hit, that means the save is already executed. #4th 断点被击中,这意味着保存已经执行。
  5. Check data before 1 minute using pgAdmin.使用 pgAdmin 在 1 分钟前检查数据。 The select query is success (the same as before it should be waiting for the lock to be lifted). select 查询成功(和之前一样,应该等待解除锁定)。 Column one value is "2".第一列的值为“2”。 This means the update is waiting for the lock to be lifted.这意味着更新正在等待解除锁定。
  6. After 1 minute #2nd breakpoint hit, then continue IDE process. 1 分钟后 #2nd 断点命中,然后继续 IDE 进程。
  7. Check data again using pgAdmin.使用 pgAdmin 再次检查数据。 Column one value is "1".第一列的值为“1”。

This means the update process is executed correctly but somehow the lock is not working for read.这意味着更新过程正确执行,但不知何故,锁无法读取。 From the article that I previously mentioned it may be due to multi-version concurrency control.从我之前提到的文章中可能是由于多版本并发控制。 If it is so then PESSIMISTIC_READ and PESSIMISTIC_WRITE has no different.如果是这样,那么 PESSIMISTIC_READ 和 PESSIMISTIC_WRITE 没有什么不同。 How can I really lock the row so no other process can select it?我怎样才能真正锁定行所以没有其他进程可以 select 呢?

Am I doing it wrong or misunderstood something?我做错了还是误解了什么?

Thank you.谢谢你。

As you read in the article, it depends of database configuration.正如您在文章中所读到的,这取决于数据库配置。 Now a standard is to configure database in REPEATABLE READ because it's give better performance, and less locks.现在一个标准是在 REPEATABLE READ 中配置数据库,因为它可以提供更好的性能和更少的锁。 isolation level . 隔离级别 AS you can see in postgres simple select are never lock.正如您在 postgres 中看到的,简单的 select 永远不会锁定。

But your test while work if testlock function use a LockModeType.PESSIMISTIC_READ.但是,如果 testlock function 使用 LockModeType.PESSIMISTIC_READ,则您的测试同时工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM