Neo4j 实体节点未在事务内部更新
在外部服务器设置中使用SDN 3.3.1和Neo4j 2.1.7 每当我执行以下执行模式时,我都有Neo4j 实体节点未在事务内部更新,neo4j,spring-data-neo4j,Neo4j,Spring Data Neo4j,在外部服务器设置中使用SDN 3.3.1和Neo4j 2.1.7 每当我执行以下执行模式时,我都有java.net.SocketTimeoutException:Read timeout: 检索实体:MyEntity entity=myRepository.findByUuid(uuid) 删除该实体的关系:neo4jooperations.query(“match(e{uuid:“theuuid”})等待了很长时间,然后得到了SocketTimeoutException 经过一些分析后,我觉得
java.net.SocketTimeoutException:Read timeout
:
MyEntity entity=myRepository.findByUuid(uuid)代码>
neo4jooperations.query(“match(e{uuid:“theuuid”})等待了很长时间,然后得到了SocketTimeoutException
127.0.0.1 - - [20/août/2015:10:47:57 +0200] "POST /db/data/transaction HTTP/1.1" 201 659 "-" "neo4j-rest-graphdb/0"
127.0.0.1 - - [20/août/2015:10:47:57 +0200] "GET /db/data/node/135/relationships/in/WITH_ROLE HTTP/1.1" 200 391 "-" "neo4j-rest-graphdb/0"
127.0.0.1 - - [20/août/2015:10:47:57 +0200] "GET /db/data/node/149 HTTP/1.1" 200 1780 "-" "neo4j-rest-graphdb/0"
127.0.0.1 - - [20/août/2015:10:47:57 +0200] "GET /db/data/node/135/relationships/out/DEFAULT_ENTITY HTTP/1.1" 200 401 "-" "neo4j-rest-graphdb/0"
127.0.0.1 - - [20/août/2015:10:47:57 +0200] "GET /db/data/node/227 HTTP/1.1" 200 1884 "-" "neo4j-rest-graphdb/0"
127.0.0.1 - - [20/août/2015:10:47:57 +0200] "GET /db/data/node/135/relationships/in/WITH_PENDING_ROLE HTTP/1.1" 200 2 "-" "neo4j-rest-graphdb/0"
所以我的第一个问题是:
- 为什么像获取实体这样的操作会生成使用事务端点的查询,而其他操作则不会
127.0.0.1 - - [20/août/2015:10:47:58 +0200] "POST /db/data/transaction/2720 HTTP/1.1" 200 254 "-" "neo4j-rest-graphdb/0"
点3.显然不会生成http请求
最后,点4.在被“阻止”一段时间(准确地说是30秒)后生成一个SocketTimeoutException
,最后生成2个http请求:
127.0.0.1 - - [20/août/2015:10:48:28 +0200] "DELETE /db/data/transaction/2720 HTTP/1.1" 200 26 "-" "neo4j-rest-graphdb/0"
127.0.0.1 - - [20/août/2015:10:48:28 +0200] "PUT /db/data/node/135/properties HTTP/1.1" 204 0 "-" "neo4j-rest-graphdb/0"
删除是因为事务已回滚,我认为PUT对应于save()
在我看来,一个僵局正在发生,因为PUT在事务之外!
因此,主要问题是:
- 为什么
在事务外部执行PUT而不是在事务内部执行POST?有没有办法强制使用事务端点执行实体更新save()
public class BusinessCard extends GenericNode {
@Indexed
private String title;
@RelatedTo(type = RelationNames.WITH_ROLE, direction = Direction.INCOMING)
private User user;
@RelatedTo(type = RelationNames.WITH_PENDING_ROLE, direction = Direction.INCOMING)
private User pendingUser;
@RelatedTo(type = RelationNames.DEFAULT_ENTITY)
private Entity defaultEntity;
}
以及该实体:
public class Entity extends GenericNode {
private String logo;
@Indexed
private String entityName;
@RelatedTo(type = RelationNames.IS_IN_CITY)
private CityNode mainCity;
@RelatedTo(type = RelationNames.IS_IN_COUNTRY)
private CountryNode mainCountry;
@RelatedTo(type = RelationNames.IS_IN_COUNTRIES)
private Set<CountryNode> countries;
@Fetch
@RelatedToVia(type = RelationNames.TRANSLATION)
private Set<EntityToEntityTranslatedContent> entityTranslatedContent;
@Fetch
@RelatedTo(type = RelationNames.HAS_KEY_STAGES)
private KeyStage lastKeyStage;
@GraphProperty(propertyType = Long.class)
private Date lastProfileUpdateDateTime;
private Integer profilCompletionIndice;
@RelatedToVia(type = RelationNames.WORKS_AT, direction = Direction.INCOMING)
private Set<BusinessCardWorkAt> employees = new HashSet<>();
...+34 more fields...
}
公共类实体扩展了GenericNode{
私人字符串标志;
@索引
私有字符串entityName;
@RelatedTo(type=RelationNames.IS\u在城市中)
私人城市节点主城;
@RelatedTo(类型=RelationNames.IS\u在\u国家/地区)
私人国家节点主要国家;
@RelatedTo(类型=RelationNames.IS_在_国家/地区)
私营国家;
@取回
@RelatedToVia(类型=RelationNames.TRANSLATION)
私有集entityTranslatedContent;
@取回
@RelatedTo(类型=RelationNames.HAS\u KEY\u STAGES)
private-KeyStage-lastKeyStage;
@GraphProperty(propertyType=Long.class)
私人日期lastProfileUpdateDateTime;
专用整数利润补全;
@RelatedToVia(类型=RelationNames.WORKS\u AT,方向=方向.传入)
私有集employees=newhashset();
…+34更多字段。。。
}
我假设您使用的是org.springframework.data.neo4j.rest.SpringRestGraphDatabase
,该数据库现已弃用,不支持正确的事务处理。(请参阅生成PUT的代码)
有一个新的基于cypher的数据库org.springframework.data.neo4j.rest.SpringCypherRestGraphDatabase
,它可以满足您的需要
你还想看看4.x版本,这是SDN的一次大修,重点是以更高效的方式远程使用neo4j而不是rest。它应该很快就会上市
本博客提供了更多解释您的实体出了问题,似乎要花很多时间将数据写入服务器。从线程转储:
at org.neo4j.rest.graphdb.ExecutingRestRequest.put(ExecutingRestRequest.java:155)
at org.neo4j.rest.graphdb.RestAPIImpl.setPropertiesOnEntity(RestAPIImpl.java:633)
at org.neo4j.rest.graphdb.entity.RestEntity.flush(RestEntity.java:189)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesTo(SourceStateTransmitter.java:109)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.write(Neo4jEntityConverterImpl.java:170)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.write(Neo4jEntityPersister.java:179)
对于转储2:
at org.neo4j.rest.graphdb.ExecutingRestRequest.put(ExecutingRestRequest.java:155)
at org.neo4j.rest.graphdb.RestAPIImpl.setPropertiesOnEntity(RestAPIImpl.java:633)
at org.neo4j.rest.graphdb.entity.RestEntity.flush(RestEntity.java:189)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesTo(SourceStateTransmitter.java:109)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.write(Neo4jEntityConverterImpl.java:170)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.write(Neo4jEntityPersister.java:179)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:247)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:235)
at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:365)
一定还有别的原因,因为
org.springframework.data.neo4j.rest.SpringCypherRestGraphDatabase
应该不使用正常的Rest端点和GET、PUT、DELETE等,而只使用普通密码
您还应该检查服务器的延迟和带宽,SDN3仍然很健谈
因此,您应该共享实体的代码,在调用save之前/何时确切执行的操作,以及向服务器发送的数据量
为了获得更好的SDN+服务器体验,我建议您看看SDN4,它是为此目的从头开始编写的。SDN4 RC2于上周五发布:
这在SDN 3.4中已修复(请参阅)。
这个jira票证内容是一个不同的主题,但您可以依赖修改后的标题“分别为基于密码的REST-API实现缺少的操作”。
从3.4开始,当使用@Transactional时,不再有事务外REST请求。我使用的是
SpringCypherRestGraphDatabase
,不是不推荐使用的数据库,但确实是您在RestAPIImpl
中指出的生成PUT的代码。我查看了SDN 4.x,在一个分支中对我们的代码进行了一些迁移,但是没有我们仍在阻止上一个RC1中的bug,这些bug阻止我们“真正地”使用它。考虑到我们的项目应该很快(9月)交付,我们决定不进行第一次交付时的迁移。顺便说一句,我已经阅读了Michael的帖子,但是,在3.3.1中,我可以做些什么来获得正确的事务行为吗?SDN4 RC2今天发布了。您可以升级到3.3.2并再次测试吗?升级到3.3.2并没有解决问题。它仍然是RestAPIImpl#setPropertiesOn使用的实体,而不是RestAPICypherImpl实体。保存操作不应使用PUT,它应使用Cypher作为其余操作。能否获取完整堆栈跟踪(线程转储)挂起时?那将非常有用。请也将它发送给我。michael at neo4j.comI向您发送了线程转储。谢谢您的帮助。我肯定在使用SpringCypherRestGraphDatabase。我的neo4j服务器位于本地主机上,因此没有延迟或带宽问题。关于我添加的单元测试,它在Neo4joOperations.save失败(卡);带有“读取超时”。
at org.neo4j.rest.graphdb.ExecutingRestRequest.put(ExecutingRestRequest.java:155)
at org.neo4j.rest.graphdb.RestAPIImpl.setPropertiesOnEntity(RestAPIImpl.java:633)
at org.neo4j.rest.graphdb.entity.RestEntity.flush(RestEntity.java:189)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesTo(SourceStateTransmitter.java:109)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.write(Neo4jEntityConverterImpl.java:170)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.write(Neo4jEntityPersister.java:179)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:247)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:235)
at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:365)
org.springframework.data.neo4j.rest.SpringCypherRestGraphDatabase