【发布时间】:2011-11-11 13:06:27
【问题描述】:
我有我的代码:
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;
}
}
主要想法是每个日期和支付系统应该有一个计算实例。 但是如果在两个不同的事务中调用这个方法,那么可能的下一个场景: 第一次事务检查,如果该日期没有计算并创建计算但仍未提交创建的计算,另一个事务检查并创建计算,则两个事务都提交。因此,每个日期将有两次计算。
如何预防?
【问题讨论】:
-
如果数据和支付系统的组合是您数据库中的唯一约束,那么您将永远无法插入重复计算
-
可以参考stackoverflow.com/questions/7839069/… 对实体进行悲观锁定。
标签: java jpa transactions