当前位置: 首页 > 知识库问答 >
问题:

为什么@transactional要将transactional范围之外的实体保存到DB?

祖迪
2023-03-14

我读过这篇文章,为什么@transactional自动保存到数据库,答案是

在事务方法返回之前,事务提交,这意味着对托管实体的所有更改都被刷新到数据库中。

但我理解托管实体是@Transactional范围内存在的实体。我还没有将obj传递到方法中,所以我不明白为什么它会自动保存。

餐厅

@Entity
@Table(name="restaurant")
@SequenceGenerator(name="restaurant_seq", sequenceName="restaurant_seq")
public class Restaurant{

    private String name;

    private String email;

    private String phonenumber;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhonenumber() {
        return phonenumber;
    }

    public void setPhonenumber(String phonenumber) {
        this.phonenumber = phonenumber;
    }

}

餐厅管理员

@RequestMapping("/restaurant")
@Controller
public class RestaurantController {

    @Autowired
    private RestaurantService restaurantRepository;

    @Autowired
    private RestaurantValidator restaurantValidator;

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.setValidator(restaurantValidator);
    }

    @GetMapping("/{id}")
    public String viewRestaurant(@PathVariable("id") Long restaurant_id, final ModelMap model) {
        Restaurant restaurant =  restaurantService.findById(restaurant_id);
        if(!model.containsAttribute("restaurantModel")){
            model.addAttribute("restaurantModel", restaurant ); 
        }
        return "pages/restaurant_view_new";
    }

    @PatchMapping("/{restaurantModel}")
    public String updateRestaurant(@Valid @ModelAttribute("restaurantModel") Restaurant editRestaurant, BindingResult bindingResult, final ModelMap model, RedirectAttributes redirectAttributes) {
        if (bindingResult.hasErrors()) {
redirectAttributes.addFlashAttribute("org.springframework.validation.BindingResult.restaurantModel", bindingResult);
            redirectAttributes.addFlashAttribute("restaurantModel", editRestaurant);
            redirectAttributes.addFlashAttribute("saveErrors", true);

            return "redirect:/restaurant/" + editRestaurant.getId();
        }
        restaurantRepository.save(editRestaurant);
        redirectAttributes.addFlashAttribute("saveSuccess", true);
        return "redirect:/restaurant/" + editRestaurant.getId();
    }
}

RestaurantValidator

@Component
public class RestaurantValidator implements Validator {

        @Autowired
        RestaurantRepository restaurantRepository;

        public boolean supports(Class clazz) {
            return Restaurant.class.equals(clazz);
        }

        public void validate(Object obj, Errors e) {
            ValidationUtils.rejectIfEmpty(e, "name", "form.required");
            ValidationUtils.rejectIfEmpty(e, "email", "form.required");
            ValidationUtils.rejectIfEmpty(e, "phonenumber", "form.required");
            Restaurant p = (Restaurant) obj;
            if(restaurantRepository.findByEmail(p.getEmail()).size() > 0 ){
                e.rejectValue("email", "form.email.duplicate");
            }
        }
}
@Transactional
public interface RestaurantRepository extends JpaRepository<Restaurant, Long>{
    List<Restaurant> findByEmail(String email);
}

共有1个答案

隗嘉歆
2023-03-14

根据我的经验,当您调用一个SELECT-语句,该语句涉及查询在持久性上下文中修改了实体的数据库表时,这会触发一个刷新。

我认为这是因为Hibernate说:“您正在对一个表进行选择,其中可能包括我这里的未刷新的实体,然后我可能会在这两个中的哪一个是最新的问题上发生冲突”。

我不知道这是否与一个特定的同花顺策略有关。

 类似资料:
  • 同事们,你能帮我做注释吗?我的目标是将数据库事务管理传递给Spring,并在当前情况下将数据保存在数据库中。 我在DAO类中有两种方法: 服务方式: 我有一个测试,调用这两种方法。我可以使用方法从表中读取数据。但是调用方法后没有保存数据。这是我的问题。当我取消注释中与事务相关的代码时,一切正常。正如我所理解的,在这种情况下,Spring事务管理器不起作用。 如何使用spring@Transacti

  • 我有一个自定义的周围实现,以匹配自定义注释。我希望自定义around在外部@transactional中执行。不幸的是,这似乎不起作用。(AOP正在工作。我看到stacktraces显示了它)。 堆栈跟踪显示我的AOP在(记录器)之前执行,MyBatis会话启动事务,MyBatis关闭事务,Spring关闭事务,然后我的AOP完成。 我认为订购我的AOP实现会有所帮助。我将返回的值设置为1。我用过

  • 问题内容: 从上一个私有方法春天在什么@Transactional属性的工作? 使用代理时,应仅将@Transactional注释应用于具有公共可见性的方法。如果使用@Transactional注释对受保护的,私有的或程序包可见的方法进行注释,则不会引发任何错误,但是带注释的方法不会显示已配置的事务设置。 我可以想到排除和方法的充分理由,但是为什么方法不能在事务上表现呢?以下堆栈跟踪显示了公共方法

  • 我可以想出排除和方法的充分理由,但为什么方法不会以事务性方式运行呢?以下stacktrace显示了公共方法(通过接口代理调用)的正确行为: 当调用一个“完全相同”的受保护方法(通过非接口CGLIB代理)时,我们得到如下结果: 这显然是一个设计决定(为什么?),但我认为它很值得怀疑的是,当它显然是开发人员的错误时,它却无声无息地失败了。 编辑这显然不是使用接口(只是接口中的公共方法)时的问题,但由于

  • 嗨,一个星期以来,我一直在追踪我的办公代码中的一个错误。它与Spring、Hibernate和Transaction有关。 我所知道的: 1.延迟加载。 2. Spring如何使用代理和拦截器进行事务管理。 3. Spring中的事务传播,我们的代码使用默认的REQUIRED。 4.每个请求/会话的会话和Hibernate的分离实体基础来保持会话,以及我们的会话不是每个会话的事实。 我的场景:我的