Hibernate 在事务仍处于打开状态并调用选择查询时提交更改

问题描述 投票:0回答:1

我遇到了一个问题,但无法理解原因。当我更新实体的列,然后在同一事务中执行选择查询时,hibernate 会反映对数据库的更改。然而,交易方法尚未完成。场景太长,我尝试用简单的方式解释它。

用户实体

public class User {
    @Id
    private Long id;
    private String name;
    private Long depertmantGuid;
}

这里是服务

@Transactional
@Service
public class Service1 {
     @Autowired
     private Service2 service2;
     public void update() {
         // other logics
        service2.update();
     } 
}

@Service
public class Service2 {
     @Autowired
     private UserService userService;
     public void update() {
         // other logics
         userService.update();
     } 
}

@Service
public class UserService {
    
   public void update() {
       User user = userRepo.findByName("user1");
       // there are lots of business logic.
       user.setName("USER1");
       userRepo.save(user);
       userRepo.findByDepartmentGuid(1234L);
       throw new RuntimeException("to run rollback mechanisim");
   }
}

@Repository
public interface UserRepo extends JpaRepository<User, Long> {
      User findByName(String name);
      List<User> findByDepartmentGuid(Long guid);
}

代码很简单。当我调用

service1.update()
方法时。它先调用
service2
,然后再调用
userService
UserService
更新用户行。 当
userRepo.findByDepartmentGuid(1234L);
行工作时,事务仍然打开,以及 hibernate 提交更改的原因。我调试了代码并将光标保留在
userRepo.findByDepartmentGuid(1234L);
行上,在 Oracle 数据库中,该值为 “user1”,在
userRepo.findByDepartmentGuid(1234L);
工作的行之后,数据库中的值为 “USER1”。另外,抛出异常并不能回滚它。

我该如何解决这种情况?

hibernate spring-data-jpa spring-data
1个回答
0
投票

Hibernate 有 4 种不同的刷新模式;

  • 手册(0),
  • 提交(5)
  • 自动(10),
  • 总是(20);

3.3.x版本之后,Hibarnate接受了AUTO刷新模式以避免脏数据。例如;如果在select查询之前相关事务中有更新操作,hibernate会先运行update查询,然后再运行select查询。因此,不会创建脏数据。

如果您不希望这种情况发生,则应将冲洗模式设置为小于10(FlushMode.AUTO)。

因此您需要在properties/yaml文件中更改hibernate的刷新模式。您可以使用此设置来解决您的问题,它会起作用。

spring.jpa.properties.org.hibernate.flushMode = COMMIT
© www.soinside.com 2019 - 2024. All rights reserved.