2014-12-02 37 views
1

示例代碼:Spring只有只讀的PROPAGATION_SUPPORTS事務,你需要提交嗎?

protected Session session() { 
     return (Session) getEntityManager().getDelegate(); 
} 

session().createCriteria(entityClass) 

會話()個createCriteria第一次調用()抱怨說,如果沒有可用的事務會話被關閉。

所以我創建使用只讀事務:

TransactionTemplate template = new TransactionTemplate(getTransactionManager()) 
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); 
template.setReadOnly(true); 

TransactionStatus status = getTransactionManager().getTransaction(template); 

我需要提交該事務。 的getTransactionManager()提交(狀態);

的問題是,如果這個承諾,我會需要另一個事務稍後爲:

criteria.list(); 

,並與該問題是第二次,這是一個不同的事務從一個用於獲取會話,並導致錯誤。它會抱怨它已經關閉。

session()。createCriteria和criteria.list必須在看起來相同的事務中使用。但是我的代碼在方法中有這些,因此除非session.createCriteria事務保持未提交狀態,否則沒有很好的方法來確保這些方法單獨工作。

我可以安全地離開TransactionDefinition.PROPAGATION_SUPPORTS事務未提交嗎?我可以創建多少次這樣的交易?

回答

3

不,你不能把它當作未經整理。只讀對於底層事務管理器來說更多的是暗示當前事務上下文中不允許突變。如果您稍後需要訪問同一個事務,也許您需要稍微改變一下設計。爲什麼不在你方法的調用者中打開事務並在那裏處理呢?或者嘗試使用基於聲明或註解的方法?

+0

是的,一個選項是打開它被調用的地方,這是我會選擇的方式。我不喜歡基於註解的方法。基於聲明的方法是什麼意思? – momomo 2014-12-02 15:01:00

+0

聲明性意味着使用XML的AOP。 – Nazgul 2014-12-02 15:01:51

+0

哦,哦。不,我喜歡我的方式。實際上,我將lambda傳遞給一個supportsTransaction方法,所以它比@Transactional方法好得多,如果你問我的話,這個方法就是一團糟,當一個新的愚蠢的開發人員接手。這幾乎就像重新學習Javascript和HTML的所有怪癖。我試圖連接AspectJ一次,但當時沒有工作。我終於破解了基於lambda方法的交易! – momomo 2014-12-02 15:05:26