我使用Spring的事務支持和JPA(Hibernate)來堅持我的實體。一切工作都應該如此,但是我在處理一個請求中的部分更新時被卡住了:Spring內的兩個JPA EntityManage管理事務?
對於每個用戶(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();
}
}
我的問題是,但是,我得到了第二次交易注入相同的EntityManager在第一。因此,刷新實體管理器(在第二個事務提交時顯式或隱式地)也會從第一個事務中清除我的骯髒的業務實體。
我該如何補救?我想爲日誌記錄部分使用第二個乾淨而新鮮的EntityManager,我知道我可以通過編程方式打開一個EntityManager,但是在這種情況下是否有更清晰的/聲明式的「Spring方法」?
編輯:
我的問題可能會從事實幹,我的第二次交易被嵌套在我的主業事務中:
|-------------- A --------------X <- Rollback of main business transaction (A)
|--- B ---| <- Commit of second log transaction (B)
我已經解決了我的問題,序列化的兩筆交易:
|--------- A --------X |--- B ---|
所以一切都很好了,但只是出於好奇:如果我會堅持我的第一種方法一nd不建議按照建議的方式使用JDBC:我將如何爲第二個(嵌套)事務配置實體管理器,以便爲新事務獲得新的實體管理器。這可以做到嗎?
想一想,我的設置有點奇怪。當我試圖寫日誌時,我的主要業務交易仍然是開放的(我在這裏使用了一個Open-In-View模式)。我可以(也可能應該)序列化這兩個交易以避免副作用...... –