我爲我的web應用程序使用每個請求模型的hibernate會話。我的jdbc事務從每個Web請求的開始處開始並在最後提交。hibernate多線程防止多重保存(),JTA有必要嗎?
//非託管環境成語
Session sess = factory.openSession();
Transaction tx = null;
try {
tx = sess.beginTransaction();
// do some work
...
tx.commit();
}
catch (RuntimeException e) {
if (tx != null) tx.rollback();
throw e; // or display error message
}
finally {
sess.close();
}
我面對,我正在測試基於幾個參數實體(A)的存在和執行INSERT只有當它不」的問題不存在。
public synchronized myMethod(param1, param2) {
MyEntityA entity = MyEntityADAO.findEntity(param1, param2)
if (entity == null) {
entity = .../create entity
MyEntityADAO.save(entity);
}
}
問題是同步沒有幫助,因爲調用MyEntityADAO.save()實際上並沒有寫入到數據庫時,當前正在運行的線程退出的方法和釋放鎖,寫入到數據庫時在交易完成之後,除了一些場景之外,這通常是我的應用程序所需要的。上面的代碼會導致在多線程環境中使用相同參數保存多個記錄。
我試着在自己的新的會話和交易執行保存代碼:以上
public synchronized myMethod(param1, param2) {
MyEntityA entity = MyEntityADAO.findEntity(param1, param2)
if (entity == null) {
entity = .../create entity
Session session = HibernateUtil.createSession();
MyEntityADAO.save(entity);
Transaction t = session.beginTransaction();
}
}
導致與2個打開的會話加載同一個集合,在某些情況下,休眠的問題。
我是否應該將每個DAO調用放在自己的事務中,並使用與JTA的事務傳播?有沒有辦法避免JTA?在調用MyEntityADAO.save()後立即調用與主會話相關的事務,並在主會話之後立即調用beginTransaction,並在請求結束時讓事務處理提交,就像現在一樣?
感謝您的輸入。我確實設置了約束,但是我沒有捕獲dao/service層中的任何hibernate/jdbc異常。似乎是一個好主意。謝謝。 – user979051 2012-02-09 22:52:31
我捕捉到ConstraintViolationException並嘗試獲取catch塊中的現有實體並獲取null..is有一些中間階段,當事務標記爲底層數據庫(mysql)中的「completed」和表約束是「更新」,但數據庫不會從表中返回新行? – user979051 2012-02-09 23:10:48
我已經嘗試刷新會話,而不是在save()之後的同步方法/塊內獲得異常但不是仍然沒有解決問題 – user979051 2012-02-09 23:26:10