我遇到以下情况。
有几个线程可以读取/更新MonthlySales
持久对象。问题是这些对象可能不存在,必须根据请求动态创建
因此,两个不同的线程最终创建对应于相同密钥的实体(即具有相同的ID),因此其中一个未能提交。我不希望这种情况发生。我希望两个线程中的一个赢得比赛而另一个线程松开,等待对象被另一个创建。
换句话说,我确实想做序列化交易。我应该使用显式Java锁(即synchronized
块)吗?
我目前的代码如下:
MonthlySales ms = entityManager.find(MonthlySales.class, somekey);
if (ms == null) { // two threads might enter this block altogether
ms = new MonthlySales();
// prepare ms object populating its fields with default values
entityManager.persist(ms);
entityManager.flush();
}
entityManager.lock(ms, LockModeType.PESSIMISTIC_WRITE); // lock this object
// since we are going to update it
// do something with ms object
entityManager.getTransaction().commit();
entityManager.close();
你能帮助我吗?
答案 0 :(得分:1)
避免竞争条件的一种方法是让具有最低ID的线程/进程/等获胜。
我相信你可以使用
访问线程IDlong threadID = Thread.currentThread().getId();
来自Java中的线程。这是比阻塞其他线程更好的竞争条件解决方案,因为这会破坏使用多个线程的目的。
参见Critical-Section Bakery算法:
http://www.basicsofcomputer.com/critical_section_problem_in_operating_system.htm