Spring管理事务中的两个JPA EntityManager?

Spring管理事务中的两个JPA EntityManager?,spring,hibernate,jpa,transactions,spring-transactions,Spring,Hibernate,Jpa,Transactions,Spring Transactions,我正在使用Spring的事务支持和JPA(Hibernate)来持久化我的实体。一切正常,但我在处理一个请求中的部分更新时遇到了麻烦: 对于每个用户(HTTP)请求,我必须将日志条目写入数据库表,即使“主”业务实体的更新失败(例如,由于验证错误)。因此,我的第一个/principal事务get被回滚,但第二个(写日志)应该提交。这似乎可以使用正确的传播级别来写入日志条目: @Repository @Transactional(propagation = Propagation.REQUIRES_

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

对于每个用户(HTTP)请求,我必须将日志条目写入数据库表,即使“主”业务实体的更新失败(例如,由于验证错误)。因此,我的第一个/principal事务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();
  }

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

我该怎么补救呢?我想为日志部分使用第二个干净、新鲜的EntityManager,我知道我可以通过编程方式打开一个,但是有更干净/声明性的“Spring方式”吗

编辑:

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

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

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

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

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


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

想一想,我有一个有点奇怪的设置。当我试图写日志时,我的主要业务事务仍然是打开的(我在这里使用的是打开的视图模式)。我可以(也可能应该)序列化这两个事务以避免副作用。。。
|--------- A --------X |--- B ---|