gpt4 book ai didi

java - 在不同线程使用时使 Web 方法同步是一个好习惯吗?

转载 作者:行者123 更新时间:2023-12-01 15:19:15 25 4
gpt4 key购买 nike

我在代码审查论坛中提出了类似的问题,但建议在这里提出这个问题。我想知道下面的网络方法中的 synchronized 关键字。由于 setPerson 是从线程池调用的(意味着不同的线程可以调用它),我应该以某种方式同步它。当我的客户端对方法进行 SOAP 调用时,EclipseLink 将使用 thead 池。我的问题是,使 Web 方法同步 是否是一个好的做法,或者我可以使用 em.lock(person, WRITE) 进行同步吗?

@Override
public synchronized void setPerson(Person person) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PersonLibPU");
EntityManager em = emf.createEntityManager();
if(!em.getTransaction().isActive()) {
em.getTransaction().begin();
}
try {
person.setPersonId(getLastInsertedId() + 1); // Get the last inserted ID and increment it by 1
em.merge(person);
em.getTransaction().commit();
emf.getCache().evict(Person.class);
} catch (Exception ex) {
if(em.getTransaction().isActive())
em.getTransaction().rollback();
} finally {
em.close();
}
}

编辑
我在上面的代码中又添加了一行,在其中设置了 person 对象的主键值。这就是同步的目的,而不是为了任何共享的 java 对象。我需要同步它,这样两个线程就无法获得相同的主键。

最佳答案

您可能问错了问题。同步在这里对您没有帮助,因为唯一存在并发问题的部分是 getLastInsertedId():您不希望两个方法获取相同的值并尝试保留具有该 ID 的实例.

只有当 setPerson 是持久保存 Person 的唯一方法时,同步它才能解决问题。

如果可能,使用底层数据存储的自动递增功能;如果做不到这一点,您的 ORM 解决方案是否会执行上下文范围的 ID 分配?最后的手段是使用 getNextId 方法,该方法可以同步并返回递增的值。这可能会导致数据库中出现不连续的 ID 序列(getNextId 将不知道持久操作是否成功),但这会减少锁定的范围。

正如 JB Nizet 指出的那样,ID 分配需要持久保存并以某种可供该数据存储的所有客户端使用的方式提供。如果您的应用程序有两个持久化 Person 实例,则需要确保它们共享一个 ID 分配器。

关于java - 在不同线程使用时使 Web 方法同步是一个好习惯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11185089/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com