// findById 执行SQL为: SELECT xxx FROM t WHERE id = ?
repository.findById(9L).ifPresent(log -> {
// 这里休眠10s方便测试并发。休眠期间,另一个请求修改了这条记录
Thread.sleep(10000);
// lock方法执行了SQL: select id from t where id =? for update,注意是加了 for update
// lock结果为:抛出 PessimisticEntityLockException 异常,加锁失败!
entityManager.lock(log, LockModeType.PESSIMISTIC_WRITE);
log.setResultMsg(RandomUtil.randomString(4));
repository.save(log);
});
结论:
第二步中lock 方法对entity 执行了一次SELECT FOR UPDATE 语句进行上锁。且由于 PostgreSQL REPEATABLE_READ实现不一样,进行 FOR UPDATE 时事务快照id与最新不一致,会导致上锁失败