我正在使用 Spring 的事务支持和 JPA (Hibernate) 来持久化我的实体。一切正常,但在处理一个请求中的部分更新时我被卡住了:
对于每个用户 (HTTP) 请求,我必须将日志条目写入数据库表,即使“主要”业务实体的更新失败(例如由于验证错误)。所以我的第一个/主要事务得到回滚,但第二个(写日志)应该提交。这似乎可以使用正确的传播级别来编写日志条目:
@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-way”来做到这一点?
编辑:
我的问题可能源于这样一个事实,即我的第二个事务嵌套在我的主要业务事务中:
|-------------- A --------------X <- Rollback of main business transaction (A)
|--- B ---| <- Commit of second log transaction (B)
我已经解决了序列化两个事务的问题:
|--------- A --------X |--- B ---|
所以现在一切都很好,但只是出于好奇:如果我坚持我的第一种方法而不是按照建议使用 JDBC:我将如何为第二个(嵌套)事务配置实体管理器,以便我得到一个新的新的交易。这可以做到吗?