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

Spring管理事务中的两个JPA实体管理器?

轩辕风华
2023-03-14

我正在使用Spring的事务支持和JPA(Hibernate)来持久化我的实体。一切正常,但我在处理一个请求中的部分更新时陷入困境:

对于每个用户(HTTP)请求,我必须将一个日志条目写入数据库表,即使“主”业务实体的更新失败(例如,由于验证错误)。因此,我的第一个/主要事务get被回滚,但第二个(写日志)应该提交。这似乎可以使用正确的传播级别来写入日志条目:

@Repository
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class UserTracker extends ... {

  @PersistenceContext private EntityManager em;

  public void log(...) {
    // create log entity and persist it
    ...
    em.persist(log);
    em.flush();
  }

}

然而,我的问题是,我在第二个事务中注入的实体管理器与第一个事务中注入的实体管理器相同。因此,刷新实体管理器(在第二个事务提交时显式或隐式地)也将刷新第一个事务中我的脏业务实体。

我如何补救这个问题?我想为日志部分使用第二个干净新鲜的实体管理器,我知道我可以以编程方式打开一个,但是有没有更干净/声明性的“Spring方式”来做到这一点?

编辑:

我的问题可能源于这样一个事实,即我的第二个事务嵌套在我的主业务事务中:

|-------------- A --------------X   <- Rollback of main business transaction (A)
                    |--- B ---|     <- Commit of second log transaction (B)

我已经解决了将两个事务序列化的问题:

|--------- A --------X |--- B ---|

所以现在一切都很好,只是出于好奇:如果我坚持第一种方法,而不是像建议的那样求助于JDBC:我将如何为第二个(嵌套的)事务配置实体管理器,以便为新事务获得一个新的实体管理器。这能做到吗?

共有1个答案

贺玉石
2023-03-14

我不确定你为什么会遇到报告中的问题,如果你的日志代码和业务逻辑代码需要更新,那么它们之间应该没有干扰。我的代码中有一个非常类似的设置。你确定交易是在你认为的地方触发的吗?您使用的是代理事务还是aspectJ事务?

如果您使用的是代理事务,那么您必须小心地通过代理来保证发送启动。

您可以做的另一件事是使用SpringJDBC模板进行用户日志记录,让@Repository同时使用EntityManager和JDBCTemboard做一些事情是非常好的,只是不要将它们混合在同一个方法中。

 类似资料:
  • 在我的实际应用程序中,我有一个业务层,它根据一些业务规则使用JPA来持久化数据,问题是camel JPA事务没有与业务层事务共享。我需要业务类中的EntityManager与Camel事务范围集成,我该怎么做? 下面是一个简单的例子,但这反映了实际设计中的问题。 项目实例 服务级别 骆驼路线 骆驼背景。xml

  • 我正在使用Spring boot 1.2.3。JPA的发布版本超过Hibernate。我遇到以下异常 以下是我的程序结构 配置类 在上面的服务类代码中,有人能指导我为什么2个工作和1个抛出异常。 谢啦

  • 我正在使用Spring(3.1.4版本)和HibernateTemplate(3.6.7.Final)以及Spring数据JPA(1.3.0版本)。我在配置文件中定义了两个事务管理器,一个用于Hibernate,另一个用于Spring数据JPA。两个事务管理器使用不同的数据源。 我想在代码中使用Hibernate的事务管理器和Spring data JPA的事务管理器。(Spring文档链接-10

  • 在我的spring服务中,我调用了两个spring数据存储库方法 现在我的查询与事务管理相关。就我所了解和看到的代码而言,spring存储库使用@Transactional为其方法启用了事务。对于select操作,它的readonly=true。 我对事务的理解是,当执行选择操作时,会创建一个事务,然后为保存操作创建另一个事务,因为对于选择操作,事务只读=true。 我希望在单个事务中执行读写操作

  • 问题内容: 我刚刚开始使用spring和hibernate进行项目。我的DAO图层类扩展了HibernateDaoSupport。我们没有使用注释。之前,我们使用了struts,因此我们使用了Session类提供的getTransaction,commit,rollback ..方法。我的要求非常简单,对于所有DAO类,如果有异常,则回滚,否则提交。请提出介绍spring交易管理的最简单方法。 问

  • 我试图使用spring boot将EntityManager注释注入到我的DAO中,但是得到一个< code > InvalidDataAccessApiUsageException 消息,说没有可用的事务EntityManager。我的印象是,只要Spring Boot从< code>application.yml中获得了我的数据源信息,并且我用< code>@PersitenceContext