閱讀

2011-11-11 59 views
0

JPA鎖定實體我有我的代碼:閱讀

public static Computation findByDateAndPaymentSystem(EntityManager em, Calendar date, PaymentSystem paymentSystem) throws SCException { 
     Query query = em.createNamedQuery("Computation.findByDateAndPaymentSystem"); 
     query.setParameter("date", date); 
     query.setParameter("ps", paymentSystem); 
     List<Computation> computationList = query.getResultList(); 
     if (computationList != null && computationList.size() > 0) { 
      if (computationList.size() == 1) { 
       return computationList.get(0); 
      } else { 
       throw new SCException("Not unique result in computation for date '" 
         + new SimpleDateFormat("dd.MM.yyyy").format(new Date(date.getTimeInMillis())) + "' and paymentSystem = '" 
         + paymentSystem.getShortName() + "'"); 
      } 
     } else { 
      Computation computation = new Computation(); 
      computation.setDate(date); 
      computation.setComputationState(ComputationState.CREATED); 
      computation.setPaymentSystem(paymentSystem); 
      em.persist(computation); 
      return computation; 
     } 
    } 

主要的想法是,我應該有每個日期和支付系統的一個計算instanse。 但是,如果在兩個不同的事務中調用此方法,那麼可能的下一個方案: 第一個事務檢查,如果沒有對此日期的計算並創建計算但仍未提交創建的計算,則另一個事務檢查並且還創建計算,承諾。因此每個日期將有兩次計算。

如何防止它?

+0

如果數據和支付系統的組合是您數據庫中的唯一約束,那麼您將永遠無法插入重複的計算 –

+0

可以參考http://stackoverflow.com/questions/7839069/lockmode-in-ejb3-persistence -namedquery/8083379#8083379對實體的悲觀鎖定。 –

回答

1

Computation.datePaymentSystem組合應該是唯一的(約束),那麼第二次插入將失敗,或者如果找到它們,您可以嘗試合併多個條目。解決方案取決於您的用例和事務策略和設置。

+0

有沒有什麼辦法在JPA的兩個字段中創建唯一的約束。這是必需的,因爲我從JPA實體生成db的shema。 – Balconsky