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

Spring/Hibernate@Transactional,如果后跟第二个@Transactional调用,则不会刷新事务

宰父跃
2023-03-14

我的Spring Boot应用程序有一个奇怪的行为。

该应用程序的“打开会话”视图为假。

我有一个控制器和一个服务,用annotation @Transactionnal公开2个方法。

Application.properties:

spring.jpa.open-in-view=false

我的服务:

@Service
public class MyService {
        @Transactional(transactionManager = "myTx")
        public void doA(Integer objectId) {
                Object o = repo.findMyObject(objectId);
                updateMyObject(o);
                repo.save(o);
        }

        @Transactional(transactionManager = "myTx")
        public void doB(Integer objectId) {
                Object o = repo.findMyObject(objectId);
                updateMyObjectDifferently(o);
                repo.save(o);
        }
}

我的控制者(案例1):

@RequestMapping("/do/{myId}")
    public String do(Model model, HttpServletRequest request) {

        service.doA(myId);
        service.doB(myId);

        return "page";
    }

使用调试中的SQL,我看到选择查询是在调用服务的过程中执行的。但是我只看到了1次刷新(几次更新),而且是在service.doB()完成并且方法周围的TransactionInterceptor启动方法invokeWithinTransaction时完成的,这很奇怪。

由于这两个方法都有@Transactional,我希望看到2次刷新:服务结束时的第一次刷新。doA()和service.doB()结束时的第二次刷新。

更奇怪的是,如果我评论第二个电话,那么

我的控制器(案例2):

@RequestMapping("/do/{myId}")
    public String do(Model model, HttpServletRequest request) {

        service.doA(myId);
        //service.doB(myId);

        return "page";
    }

在案例1中,它就像服务。doA()知道第二个调用将在同一对象上紧接着到达,因此它不会提交/刷新事务并等待service.doB()结束。

为什么我只看到1次刷新?是因为两个调用都在一些数据库对象上吗?

我以为我对@Transactional的了解还可以。但是现在,我迷路了。

共有1个答案

梁丘扬
2023-03-14

Hibernate将检测一个对象是否真的是脏的,如果没有必要,将避免发送UPDATE语句。我假设您的updateMyObject根本没有改变实体相对于最初加载时的状态。

 类似资料:
  • 我已经开始使用这里描述的Guice方法级事务。我有一条消息,比如 从简短的描述中,我认为wis应该就足够了。但是我收到一个错误,因为没有启动任何事务。只有当我自己启动并提交它时,它才有效。 对象是由Guice在初始化程序中的应用程序的开始时创建的。每个请求使用相同的实例。 为什么它不起作用?

  • 问题内容: 我在Web应用程序中使用 Spring 3.1 + Hibernate4.x 。在我的DAO中,我将用户类型对象保存如下 但是出现以下异常: 我用谷歌搜索并找到了类似的问题,有以下解决方案: 那解决了问题。但是在该解决方案中,手动开始和提交事务有很多麻烦。 没有手动开始/提交交易,我不能直接使用 吗? 我也尝试在服务/ dao方法上使用,但是问题仍然存在。 编辑: 这是我的Spring

  • 但获得以下异常: 我搜索了一下,在SO上找到了类似的问题,解决方法如下: 这就解决了问题。但在该解决方案中,手动开始和提交事务会有很多麻烦。 请帮帮忙。

  • 我有一个非常基本的Spring Boot/JPA stack应用程序,它有一个控制器、服务层和存储库,它不像我所理解的那样持久更新。 微不足道的实体: 一个微不足道的存储库: 一个简单的服务层: 和一个REST控制器,它全部使用: 我启用了SQL调试日志,并查看了selects、update等。 使用上面的代码:当服务方法被控制器调用时,修改的实体不持久化。SQL日志显示实体的,但没有。 如果没有

  • 在我开始这看似很长的一段之前,我想对我可能收到的任何建议/建议表示感谢。朱约翰 我开发了一个简单的测试来帮助我理解spring的声明性(@Transactional)事务管理框架如何与spring的RESTful web服务结合使用。 为此,我开发了以下RESTful控制器: 其中,“tester”是以下服务类的bean,并自动连接到此控制器。类中唯一的方法是事务性的: 在上面,GenericDB

  • 问题内容: 我想知道当你使用注释方法时实际发生了什么?当然,我知道Spring将把该方法包装在Transaction中。 但是,我有以下疑问: 听说Spring创建了代理类?有人可以更深入地解释这一点。该代理类中实际包含什么?实际班级会怎样?我怎么能看到Spring创建的代理类 我还在Spring文档中读到: 注意:由于此机制基于代理,因此仅会拦截通过代理传入的“外部”方法调用。这意味着“自调用”