gpt4 book ai didi

java - Spring 数据 Neo4j : Indefinite waiting for RWLock without DeadlockDetectedException

转载 作者:行者123 更新时间:2023-12-01 10:14:49 30 4
gpt4 key购买 nike

在我的项目中,我使用 Spring Data Neo4j (3.4.2.RELEASE) 以及使用嵌入式数据库的基于 AspectJ 的“高级映射”模式。我还通过@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)使用基于AspectJ的事务管理

在我的应用程序中,在并发读取/写入数据库的情况下,我遇到了死锁。但我没有收到 DeadlockDetectedException,而是看到一个线程无限期地等待 RWLock。此后不久,所有剩余线程将等待第一个线程,并且应用程序将停止并无法恢复。其他线程可能也已经获得了锁,但由于我看不到,所以我不确定。

锁定线程的堆栈跟踪:

Thread [Processing-XXX] (Suspended) 
owns: SeasonOfCompetitionRepositoryImpl (id=134)
waiting for: RWLock (id=174)
Object.wait(long) line: not available [native method]
RWLock(Object).wait() line: 502 [local variables unavailable]
RWLock.acquireWriteLock(Object) line: 388
LockManagerImpl.getWriteLock(Object, Object) line: 66
CommunityLockClient.acquireExclusive(Locks$ResourceType, long) line: 116
LockingStatementOperations.relationshipCreate(KernelStatement, int, long, long) line: 287
OperationsFacade.relationshipCreate(int, long, long) line: 866
NodeProxy.createRelationshipTo(Node, RelationshipType) line: 559
DelegatingGraphDatabase.getOrCreateRelationship(Node, Node, RelationshipType, Direction, Map<String,Object>) line: 298
Neo4jTemplate.getOrCreateRelationship(Node, Node, RelationshipType, Direction, Map<String,Object>) line: 772
RelationshipHelper.createSingleRelationship(Node, Node) line: 198
RelationshipHelper.createAddedRelationships(Node, Set<Node>) line: 154
RelatedToSingleFieldAccessorFactory$RelatedToSingleFieldAccessor(RelatedToFieldAccessor).createAddedRelationships(Node, Set<Node>) line: 78
RelatedToSingleFieldAccessorFactory$RelatedToSingleFieldAccessor.setValue(Object, Object, MappingPolicy) line: 68
NodeEntityState(DefaultEntityState<STATE>).setValue(Neo4jPersistentProperty, Object, MappingPolicy) line: 113
DetachedEntityState<STATE>.setValue(Neo4jPersistentProperty, Object, MappingPolicy) line: 181
DetachedEntityState<STATE>.setValue(Field, Object, MappingPolicy) line: 145
SeasonOfCompetition.season_aroundBody21$advice(SeasonOfCompetition, SeasonOfCompetition, Season, JoinPoint, Neo4jNodeBacking, NodeBacked, Object, AroundClosure, JoinPoint) line: 266
SeasonOfCompetition.setSeason_aroundBody22(SeasonOfCompetition, Season) line: 108
SeasonOfCompetition$AjcClosure23.run(Object[]) line: 1
AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(Object, AroundClosure) line: 66
AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation() line: 72
AnnotationTransactionAspect(TransactionAspectSupport).invokeWithinTransaction(Method, Class<?>, InvocationCallback) line: 281
AnnotationTransactionAspect(AbstractTransactionAspect).ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(Object, AroundClosure, JoinPoint$StaticPart) line: 70
SeasonOfCompetition.setSeason(Season) line: 95
SeasonOfCompetitionRepositoryImpl.getOrCreate_aroundBody0(SeasonOfCompetitionRepositoryImpl, Season, Competition) line: 32
SeasonOfCompetitionRepositoryImpl$AjcClosure1.run(Object[]) line: 1
AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(Object, AroundClosure) line: 66
AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation() line: 72
AnnotationTransactionAspect(TransactionAspectSupport).invokeWithinTransaction(Method, Class<?>, InvocationCallback) line: 281
AnnotationTransactionAspect(AbstractTransactionAspect).ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(Object, AroundClosure, JoinPoint$StaticPart) line: 70
SeasonOfCompetitionRepositoryImpl.getOrCreate(Season, Competition) line: 26

这是自定义 RepositoryExtension 的一部分,应该为给定参数创建唯一的 SeasonOfCompetition:

@Override
@Transactional
public synchronized SeasonOfCompetition getOrCreate(Season season, Competition competition)
{
String uri = buildUri(season, competition);
SeasonOfCompetition soc = getOrCreateByUri(uri);
if(soc.getSeason() == null)
{
soc.setSeason(season);
}
if(soc.getCompetition() == null)
{
soc.setCompetition(competition);
}
return soc;
}

请注意,我已经使用了 @Transactionalsychronized - 这两个我最初没有使用,因为我认为(但我不确定)这里不需要它们。

这是线程卡住的领域实体SeasonOfCompetition的选择:

@NodeEntity
public class SeasonOfCompetition extends UriEntity
{
@RelatedTo(type = "inSeason", direction = Direction.OUTGOING)
private Season season;

@Transactional
public void setSeason(Season season)
{
this.season = season;
}
}

我在这里做错了什么?我假设通过 SDN 访问图形数据库是线程安全的,并且除了使用事务之外不需要任何特殊处理。也欢迎提供有关如何调试此问题或如何使其在这种情况下抛出 DeadlockDetectedException 的建议。

我以前也遇到过其他与并发相关的问题(本应是唯一的重复实体、重复关系等),并且不完全理解我还需要如何处理这个问题。欢迎提供有关如何为 NodeEntities 和关系实现线程安全的 #getOrCreate 的意见。

编辑:我尝试实现基于 MERGE 查询的 #getOrCreate 版本,该版本不使用@cybersam 建议的任何自定义同步:

@Override
@Transactional
@SuppressWarnings("deprecation")
public T getOrCreateByUri(String uri)
{
checkArgument(!StringUtils.isEmpty(uri));

Class<T> clazz = getEntityType();
String queryString = "MERGE (n:" + clazz.getSimpleName() + " {uri: {uri}}) RETURN n";
Map<String, Object> parameters = new HashMap<>();
parameters.put("uri", uri);
Node node = (Node) template.getGraphDatabase().queryEngine().query(queryString, parameters).single().get( "n" );
template.postEntityCreation(node, clazz);
T result = (T) template.convert(node, clazz);
return result.persist();
}

但是这无法创建唯一的节点。创建 100 个线程并并行调用它的简单测试会失败,因为创建了多个节点。这可能与 result.persist() 有关,但如果没有,返回的实体不会附加到图表中,并且会丢失一些信息。

最佳答案

neo4j documentation包含此警告:

Important

Deadlocks caused by the use of other synchronization than the locks managed by Neo4j can still happen. Since all operations in the Neo4j API are thread safe unless specified otherwise, there is no need for external synchronization. Other code that requires synchronization should be synchronized in such a way that it never performs any Neo4j operation in the synchronized block.

执行 Neo4j 操作的

getOrCreate() 目前已同步。所以,死锁有可能实际上是由你自己代码的Java同步引起的。您将需要重新设计代码以避免在执行 Neo4j 操作时使用 Java 同步。

关于java - Spring 数据 Neo4j : Indefinite waiting for RWLock without DeadlockDetectedException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35962837/

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