Spring Data Jpa 隔离级别不起作用吗?

Is the Spring Data Jpa isolation level not working?

提问人:Ban 提问时间:11/11/2023 最后编辑:Ban 更新时间:11/11/2023 访问量:29

问:

环境

  • 春季启动 3.1.5
  • MySQL的8.031

我的想法如下

  1. 启动隔离级别设置为 SERIALZABLE 的事务。
  2. 如果上述 SERIALZABLE 事务没有完成,但另一个事务开始,它将在 SERIALZABLE 事务完成后运行。

隔离代码

@Slf4j
@Service
@RequiredArgsConstructor
public class PersonService {

    private final PersonRepository personRepository; // JpaRepository
    private Long wait = 5000L;

    @Transactional(isolation = Isolation.SERIALIZABLE)
    public List<Person> findAllSERIALIZABLE() throws InterruptedException {
        log.info("SERIALIZABLE ALL start");
        List<Person> all = personRepository.findAll();
        Person person = all.get(0);
        person.setName(String.valueOf(System.currentTimeMillis()));
        Person person1 = all.get(1);
        person1.setName(String.valueOf(System.currentTimeMillis()));
        Thread.sleep(wait);
        log.info("SERIALIZABLE ALL end");
        return personRepository.saveAllAndFlush(all);
    }

    public List<Person> find1And2() {
        log.info("1,2 find start");
        List<Person> allById = personRepository.findAllById(List.of(1L,2L));
        log.info("1,2 find end");
        return allById;
    }
}

测试代码

    @Test
    @DisplayName("SERIALIZABLE find test")
    public void serializableFindTest() throws InterruptedException, ExecutionException {
        CompletableFuture<List<Person>> serializableAll = CompletableFuture.supplyAsync(() -> {
            try {
                return personService.findAllSERIALIZABLE();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        Thread.sleep(1000);

        CompletableFuture<List<Person>> find1And2 = CompletableFuture.supplyAsync(() -> personService.find1And2());

        List<Person> people = serializableAll.get();
        List<Person> people1 = find1And2.get();

        // then
        Assertions.assertEquals(people1.get(0).getName(),people.get(0).getName());
    }

我以为顺序会是

1.可序列化所有开始、结束

2. find1和2开始、结束

但结果是不同的。

2023-11-11T14:23:04.585+09:00  INFO 18864 --- [onPool-worker-1] com.tx.test.service.PersonService        : SERIALIZABLE ALL start
2023-11-11T14:23:04.702+09:00 DEBUG 18864 --- [onPool-worker-1] org.hibernate.SQL                        : 
    select
        p1_0.id,
        p1_0.name 
    from
        person p1_0
Hibernate: 
    select
        p1_0.id,
        p1_0.name 
    from
        person p1_0
2023-11-11T14:23:05.581+09:00  INFO 18864 --- [onPool-worker-2] com.tx.test.service.PersonService        : 1,2 find start
2023-11-11T14:23:05.605+09:00 DEBUG 18864 --- [onPool-worker-2] org.hibernate.SQL                        : 
    select
        p1_0.id,
        p1_0.name 
    from
        person p1_0 
    where
        p1_0.id in (?,?)
Hibernate: 
    select
        p1_0.id,
        p1_0.name 
    from
        person p1_0 
    where
        p1_0.id in (?,?)
2023-11-11T14:23:05.610+09:00  INFO 18864 --- [onPool-worker-2] com.tx.test.service.PersonService        : 1,2 find end
2023-11-11T14:23:09.822+09:00  INFO 18864 --- [onPool-worker-1] com.tx.test.service.PersonService        : SERIALIZABLE ALL end
2023-11-11T14:23:09.887+09:00 DEBUG 18864 --- [onPool-worker-1] org.hibernate.SQL                        : 
    update
        person 
    set
        name=? 
    where
        id=?
Hibernate: 
    update
        person 
    set
        name=? 
    where
        id=?
2023-11-11T14:23:09.891+09:00 DEBUG 18864 --- [onPool-worker-1] org.hibernate.SQL                        : 
    update
        person 
    set
        name=? 
    where
        id=?
Hibernate: 
    update
        person 
    set
        name=? 
    where
        id=?

org.opentest4j.AssertionFailedError: 

我不确定是否我对隔离级别了解不够,或者我是否设置不正确。

mysql jpa spring-data-jpa 事务 隔离级

评论


答: 暂无答案