Hibernate使用Spring数据管理并发事务

时间:2018-06-22 10:13:28

标签: java oracle hibernate spring-data-jpa locking

我有一个api更新数据库中的某些记录。我可能有多台计算机运行相同的应用程序,所以我不能用程序而是用数据库锁定它。我想在读取记录时“锁定”记录,并在将值更新到数据库后释放记录。如果两个请求一起(或在很短的时间内)到达服务器,我希望一个计算可以等待另一个请求的交易结束,并基于另一个请求的值。

例如,

| <-- database has a record whose value is 1
|
| <-- request 1 arrives and get the record with value 1 and lock the record
| <-- request 2 arrives and find the record is locked therefore wait until it is ready
|
| <-- request 1 calculate value += 1
|
| <-- request 1 update the record and unlock the record
|
| <-- record has value of 2 now
|
| <-- request 2 can get the record now, whose value is 2 and lock the record
|
| <-- request 2 calculate value += 1
|
| <-- request 2 update the record and unlock the record
|
| <-- record has value of 3 now
|
v

我使用的数据库是Oracle。我正在使用Spring Data JPA运行查询。我尝试过的是:

控制器:

@GetMapping("/lock")
public @ResponseBody
String pessimisticLock() throws InterruptedException {
    testService.readAddOneThenSave();
    return "Hello World";
}

服务:

@Transactional // to release lock after the method ends
public void readAddOneThenSave() throws InterruptedException {

    // get the record and lock it with PESSIMISTIC_WRITE
    TestLock testLock = testLockRepository.findById(1L);
    // but both machine show the original value :(
    logger.info("testLock: {}", testLock);

    // to simulate two requests arrive same time
    Thread.sleep(5000);

    Long value = testLock.getValue();
    logger.info("value: {}", value);

    testLock.setValue(value + 1);
    testLockRepository.save(testLock);
}

存储库:

// lock when called and release until end of transaction
@Lock(LockModeType.PESSIMISTIC_WRITE) 
TestLock findById(Long id);

我尝试在两台计算机上运行该应用程序,并在“相同”时间提出请求。在第一个请求结束后,第二个请求开始查找记录,但是即使在后一个请求的计算机上,我仍然从两台计算机上获得了相同的记录(值= 1)。然后,我将从上面的示例中得到值2的结果,这不是我想要的。

我对PESSIMISTIC_WRITE的理解正确吗?

感谢您的帮助。谢谢!

0 个答案:

没有答案