Hibernate在事务仍然打开并调用select query时提交更改

ars1skjm  于 2023-10-23  发布在  其他
关注(0)|答案(1)|浏览(144)

我遇到了一个问题,不明白原因。当我更新实体的一列,然后在同一事务中执行选择查询时,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然后调用userServiceUserService更新用户行。当userRepo.findByDepartmentGuid(1234L);行工作时,事务仍然打开,为什么Hibernate提交更改。我调试代码,并保持光标在行userRepo.findByDepartmentGuid(1234L);上的值是**“user1”在Oracle数据库中,后行userRepo.findByDepartmentGuid(1234L);是工作的值是“USER1”**在数据库中。此外,抛出异常也不能回滚它。
我该如何解决这种情况?

fv2wmkja

fv2wmkja1#

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

  • (0),
  • 承诺(5)
  • (10),
  • ALWAYS(20);

在3.3.x版本之后,Hibernate接受了AUTO刷新模式以避免脏数据。比如说;如果在select查询之前的相关事务中有update操作,hibernate将首先运行update查询,然后再运行select查询。因此,将不会创建脏数据。
如果不希望出现这种情况,则应将刷新模式设置为小于10(FlushMode.AUTO)。
因此,您需要在properties/yaml文件中更改hibernate的刷新模式。您可以使用此设置来解决您的问题,并且它会起作用。

spring.jpa.properties.org.hibernate.flushMode = COMMIT

相关问题