删除记录然后在同一 Spring 事务中选择仍然 returns 已删除的记录

Deleting a record then selecting within the same Spring Transaction still returns the deleted record

我在隔离级别设置为 SERIALIZABLE 的 spring 事务中有一些代码。这段代码做了一些事情,首先它删除了 table 中设置了标志的所有记录,接下来它执行 select 以确保不能写入无效记录,最后写入新记录。

问题是 select 继续 return 如果代码是带有事务注释的 运行 被删除的记录。我的理解是,因为我们在同一个 spring 事务中执行这些操作,所以在执行 select.

时将考虑先前的删除操作

我们正在使用 Spring Boot 2.1 和 Hibernate 5.2

代码摘要如下所示:

@HystrixCommand
public void deleteRecord(EntityObj entityObj) {
    fooRepository.deleteById(entityObj.getId());
    //Below line added as part of debugging but I don't think I should really need it?
    fooRepository.flush();
}


public List<EntityObj> findRecordByProperty(final String property) {
    return fooRepository.findEntityObjByProperty(property);
}

@Transactional(isolation = Isolation.SERIALIZABLE)
public void debugReadWrite() {

    EntitiyObject entitiyObject = new EntityObject();
    entitiyObject.setId(1);
    deleteRecord(entitiyObject);
    List<EntityObj> results = findRecordByProperty("bar");
    if (!results.isEmpty()) {
        throw new RuntimeException("Should be no results!")
    }
}

交易尚未提交,您需要先完成交易再查找记录。

用 propagation = Propagation.REQUIRES_NEW) 修饰 deleteRecord 应该可以解决问题

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void deleteRecord(EntityObj entityObj) {
    fooRepository.deleteById(entityObj.getId());
    // flush not needed fooRepository.flush();
}

不需要刷新,因为当 deleteRecord 完成时将提交转换。

引擎盖下

//start transaction
public void deleteRecord(EntityObj entityObj) {

    fooRepository.deleteById(entityObj.getId());

}
//commit transaction

原来这个问题是由于我们使用了 Hystrix。事务在 Hystirx 之外启动,然后在稍后通过 Hystrix 命令进行。 Hystrix 命令正在使用线程池,因此在 Hystrix 线程池的新线程上执行时事务会丢失。有关详细信息,请参阅此 github 问题: https://github.com/spring-cloud/spring-cloud-netflix/issues/1381