Spring 与 Isolation.SERIALIZABLE 的事务不会锁定数据库行以进行更新

Spring Transactional with Isolation.SERIALIZABLE does not lock database row for updates

我有一个带有 H2 数据库的 Spring 引导应用程序,我已经实现了一个带有注释的服务,以使用隔离级别为 SERIALIZABLE 的事务。 计划是将数据集锁定在数据库中,这样并发进程就无法在我的服务仍在保存要更新的数据时更新数据库。

@Transactional(isolation = Isolation.SERIALIZABLE) public class MyService {

  public OrderResource addContract(final Long orderId, final ContractResource contractResource) {

    // fetch the contract with Spring Data JPA repository
    final Contract contract = contractRepository.findById(contractId);

    // to test the scenario manually I wait for 10 seconds. In this timespan I manually change the row in the database
    try {
      Thread.sleep(10000);
    } catch (final InterruptedException e) {
      e.printStackTrace();
    }

    updateService.addContract(contract, contractResource);

  }
}

我现在希望受影响的记录被锁定在数据库中(例如通过像 'SELECT FOR UPDATE' 这样的 Hibernate 生成的语句),但事实并非如此。

除了“Isolation.SERIALIZABLE”,我还需要注意其他什么才能实现吗?

Serializable 隔离级别并不一定意味着独占数据库锁。例如,PostgreSQL 实现了 Serializable Snapshot Isolation pattern. The database will check possible serializable anomalies before committing. The behaviour is similar to the optimistic locking approach.

如果您想要 select 具有独占锁的行,您可能应该直接应用 SELECT FOR UPDATE。如果你想坚持使用 JPA,那么你可以尝试使用 Lock query annotation.