gpt4 book ai didi

java - 使用 OpenJPA 时 ORM 出现死锁

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

使用 Soap UI 运行 10 个线程执行负载测试时,我遇到了死锁,每个线程向我的 Web 服务发出 10 个请求,该服务调用 OpenJPA 实体管理器的 persists 方法。

然后我执行单个请求,一切顺利,但在多线程环境中最终会出现死锁。

我收到的错误是:

Deadlock found when trying to get lock; try restarting transaction {prepstmnt 12796448 UPDATE Assessment SET dateCompleted = ? WHERE id = ? [params=?, ?]} [code=1213, state=40001]

因死锁而崩溃的方法是这样的:

@Override
public AssessmentKey update(AssessmentKey assessmentKey) {
OpenJPAEntityManager openJpaEntityMgr = OpenJPAPersistence.cast(entityManager);
for (Assessment assessment : assessmentKey.getAssessments()) {
if (!entityManager.contains(assessment) && !openJpaEntityMgr.isDetached(assessment)) {
LOGGER.debug("Persisting {}", assessment);
entityManager.persist(assessment);
}
}
return entityManager.merge(assessmentKey);
}

Assessment是OpenJPA的一个实体,它只是一个包含JPA注释的普通实体。如果您需要它的代码,请索要。

我了解了死锁是如何发生的,如何解决它们在here中提到。 。但是如何在 ORM 中解决它们我无法找到答案。

我的 persistence.xml 文件如下所示:

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="com.groupgti.esb.online.tests">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>com.groupgti.esb.assessments.model.jpaimpl.Assessment</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<validation-mode>NONE</validation-mode>
<properties>
<property name="openjpa.Log" value="slf4j"/>
<property name="openjpa.DataCache" value="false"/>
<property name="openjpa.ReadLockLevel" value="none"/>
<property name="openjpa.WriteLockLevel" value="pessimistic-write"/>
<property name="openjpa.LockTimeout" value="10000"/>
<property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/>
</properties>
</persistence-unit>
</persistence>

整个应用程序使用Spring,并且完成事务的类被标记为@Transactional。 ORM中如何解决这个死锁问题?

编辑:

AssessmentKeyAssessment 相关:

@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, mappedBy = "assessmentKey")
private List<Assessment> assessments = new ArrayList<Assessment>();

AssessmentAssessmentKey看起来像这样:

@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@Index
@Column(nullable = false)
@ForeignKey
private AssessmentKey assessmentKey;

最佳答案

AssessmentKeyAssessmentOneToMany 双向关系。OneToManyManyToOne 都是双向关系> 注释有 CascadeType.PERSIST 等。

要点是:

EntityManager持续存在Assessment时,AssessmentKey也会持续存在。您应该需要再次保留或合并 AssessmentKey

让我建议如下 OR 映射:

AssessmentKey.java

@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, 
mappedBy = "assessmentKey", orphanRemoval=true)
private List<Assessment> assessments;

评估.java

@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.REFRESH})
@JoinColumn(name = "ASSESSMENT_ID", referencedColumnName = "ID")
private AssessmentKey assessmentKey;

数据库操作

@Override
public AssessmentKey update(AssessmentKey assessmentKey) {
OpenJPAEntityManager openJpaEntityMgr = OpenJPAPersistence.cast(entityManager);
// there may be your operation
return entityManager.merge(assessmentKey);
}

我假设,当前AssessmentKey对象的Assessment值可能如下

On System                               |   In Existing Database
ID Description | ID Descrition
1001 AAA => No Changes | 1001 AAA
1002 BBB => Need to update | 1002 BB
null DDD => Need to add | 1003 CCC => need to remove.

当EntityManager合并AssessmentKey时,EntityManager将完​​成Assessment的所有过程,正如我在上面的数据结构中提到的。

注意:确保 OneToMany 注释中的 orphanRemoval=true

关于java - 使用 OpenJPA 时 ORM 出现死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13030875/

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