2

我处于以下情况。

有几个线程可以读取/更新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();

你能帮助我吗?

4

1 回答 1

1

避免竞争条件的一种方法是让 ID 最低的线程/进程/等获胜。

我相信您可以使用访问线程 ID

long threadID = Thread.currentThread().getId();

从Java中的线程内部。这是比阻塞其他线程更好的竞争条件解决方案,因为这会破坏使用多个线程的目的。

请参阅关键部分面包店算法:

http://www.basicsofcomputer.com/critical_section_problem_in_operating_system.htm

在 JPA 的情况下,根据herehere,最佳实践方法似乎是同时尝试修改事物,并在事情不成功时捕获异常。

于 2012-06-13T03:44:31.497 回答