删除记录然后在同一 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
我在隔离级别设置为 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