【发布时间】:2012-10-23 12:54:56
【问题描述】:
在使用Soap UI 执行负载测试时遇到死锁,每个线程运行 10 个线程向我的 Web 服务发出 10 个请求,该服务调用 OpenJPA 实体管理器的 persits 方法。
然后我执行单个请求,一切都很好,但在多线程环境中它最终会出现死锁。
我得到的错误是:
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中如何解决这个死锁问题?
编辑:
AssessmentKey 与Assessment 有关系:
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, mappedBy = "assessmentKey")
private List<Assessment> assessments = new ArrayList<Assessment>();
而在Assessment AssessmentKey 看起来像这样:
@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@Index
@Column(nullable = false)
@ForeignKey
private AssessmentKey assessmentKey;
【问题讨论】:
-
@Could you post
O/RAssessmentKey和Assessment的关系?
标签: java jpa orm deadlock openjpa