如果实体已经加载一次,则外部事务无法从内部事务中检索更改
Outer transaction can not retrieve changes from inner transaction if entity already loaded once
- 我有一个
@Transactional
从存储库加载实体的主要服务。
- 然后此服务调用具有
@Transactional(propagation = Propagation.REQUIRES_NEW)
加载相同实体以更新其属性之一的子服务
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateEntity(Long id) {
repository.findById(id).get().setName("NEW NAME");
}
- 不幸的是,从子服务完成的更新在主服务中是不可见的,即使我尝试从存储库重新加载实体,无论我选择哪个隔离级别(READ_UNCOMMITTED,READ_COMMITTED、REPEATABLE_READ、可序列化)。
这是主要服务的代码:
@Transactional
public void transactional() {
MyEntity myEntity1 = repository.findById(1L).get();
log.info("{} - {}", myEntity1, myEntity1.getName()); // "OLD NAME"
subService.updateEntity(1L);
MyEntity myEntity2 = repository.findById(1L).get();
log.info("{} - {}", myEntity2, myEntity2.getName()); // "OLD NAME" again, and same reference as myEntity1
}
尽管如此,如果我在调用子服务之前不在主服务中加载一次实体,我确实会看到内部事务的变化。
@Transactional
public void transactional() {
subService.updateEntity(1L);
MyEntity myEntity2 = repository.findById(1L).get();
log.info("{} - {}", myEntity2, myEntity2.getName()); // "NEW NAME"
}
我想我想要实现的不是标准的做事方式,但我真的很想了解为什么如果一个实体在外部事务中加载一次,我就无法从内部事务中检索更改.
从内部事务编辑后,必须通过调用 EntityManager#refresh
在外部事务中显式重新加载实体。 (感谢 @M.Prokhorov 的线索)
entityManager.refresh(myEntity1);
正如@Kayaman 在评论我的问题时所说:
It's the 1st level cache in action. It won't reload the entity (unless
explicitly told to), since you've just loaded it.
- 我有一个
@Transactional
从存储库加载实体的主要服务。 - 然后此服务调用具有
@Transactional(propagation = Propagation.REQUIRES_NEW)
加载相同实体以更新其属性之一的子服务
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateEntity(Long id) {
repository.findById(id).get().setName("NEW NAME");
}
- 不幸的是,从子服务完成的更新在主服务中是不可见的,即使我尝试从存储库重新加载实体,无论我选择哪个隔离级别(READ_UNCOMMITTED,READ_COMMITTED、REPEATABLE_READ、可序列化)。
这是主要服务的代码:
@Transactional
public void transactional() {
MyEntity myEntity1 = repository.findById(1L).get();
log.info("{} - {}", myEntity1, myEntity1.getName()); // "OLD NAME"
subService.updateEntity(1L);
MyEntity myEntity2 = repository.findById(1L).get();
log.info("{} - {}", myEntity2, myEntity2.getName()); // "OLD NAME" again, and same reference as myEntity1
}
尽管如此,如果我在调用子服务之前不在主服务中加载一次实体,我确实会看到内部事务的变化。
@Transactional
public void transactional() {
subService.updateEntity(1L);
MyEntity myEntity2 = repository.findById(1L).get();
log.info("{} - {}", myEntity2, myEntity2.getName()); // "NEW NAME"
}
我想我想要实现的不是标准的做事方式,但我真的很想了解为什么如果一个实体在外部事务中加载一次,我就无法从内部事务中检索更改.
从内部事务编辑后,必须通过调用 EntityManager#refresh
在外部事务中显式重新加载实体。 (感谢 @M.Prokhorov 的线索)
entityManager.refresh(myEntity1);
正如@Kayaman 在评论我的问题时所说:
It's the 1st level cache in action. It won't reload the entity (unless explicitly told to), since you've just loaded it.