gpt4 book ai didi

java - 在处理来自 @Index(unique=true) 的 ClientException 后,对 Neo4j 的所有后续调用都会卡住

转载 作者:行者123 更新时间:2023-11-30 06:41:53 30 4
gpt4 key购买 nike

我有一个 Spring boot 应用程序,该应用程序的实体在字段上具有唯一性约束。

我正在运行 spring-boot、spring-data-neo4j、neo4j-ogm、bolt-driver 和 neo4j 3.2 docker 镜像。

当我运行 IT 测试时,我首先保留一些数据,然后尝试保留相同的数据以触发约束。

唯一性约束按预期生效并引发 ClientException。这将被捕获并向客户端返回一个适当的异常。

然后在下面的测试中,我只是尝试保存一些数据,突然服务器在 GraphRepository 中运行 save() 时卡住了。

所以我的问题是,在由于唯一性约束而引发 ClientException 后,为什么 Neo4j 在我的情况下在所有后续事务中完全卡住。日志什么也没说,neo4j debug.log 什么也没说。

如果我单独运行每个测试,它们都会通过。一起运行,在测试完约束后,它会在测试中卡住 neo4j。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<groupId>se.andolf</groupId>
<artifactId>lift</artifactId>
<version>0.0.1-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>

<modules>
<module>lift-api</module>
<module>lift-service</module>
<module>lift-app</module>
</modules>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring.boot.version>1.5.3.RELEASE</spring.boot.version>
<spring-data-releasetrain.version>Ingalls-SR3</spring-data-releasetrain.version>
<neo4j-ogm.version>2.1.2</neo4j-ogm.version>
</properties>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-releasetrain</artifactId>
<version>Ingalls-SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>se.andolf</groupId>
<artifactId>lift-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>se.andolf</groupId>
<artifactId>lift-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>se.andolf</groupId>
<artifactId>lift-service</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-core</artifactId>
<version>${neo4j-ogm.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-bolt-driver</artifactId>
<version>${neo4j-ogm.version}</version>
</dependency>
<dependency>
<groupId>com.github.jmnarloch</groupId>
<artifactId>modelmapper-spring-boot-starter</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.uuid</groupId>
<artifactId>java-uuid-generator</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-patch</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>3.0.3</version>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.11</version>
</plugin>
</plugins>
</pluginManagement>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>integration-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-prepare-agent-integration</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-report-integration</id>
<goals>
<goal>report-integration</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>coveralls</id>
<build>
<plugins>
<plugin>
<groupId>org.eluder.coveralls</groupId>
<artifactId>coveralls-maven-plugin</artifactId>
<version>4.3.0</version>
</plugin>
</plugins>
</build>
</profile>
</profiles>

lift-service/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>lift</artifactId>
<groupId>se.andolf</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>

<artifactId>lift-service</artifactId>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>se.andolf</groupId>
<artifactId>lift-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-core</artifactId>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-bolt-driver</artifactId>
</dependency>
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-patch</artifactId>
</dependency>
<dependency>
<groupId>com.github.jmnarloch</groupId>
<artifactId>modelmapper-spring-boot-starter</artifactId>
</dependency>
</dependencies>

session bean配置:

@Configuration
@EnableNeo4jRepositories(basePackages = "se.andolf")
@EnableTransactionManagement
public class SessionConfig {

@Bean
public SessionFactory sessionFactory(){
LOG.debug("Loading session factory");
return new SessionFactory("se.andolf");
}

@Bean
public Neo4jTransactionManager transactionManager() {
return new Neo4jTransactionManager(sessionFactory());
}
}

CategoryController.class

@RestController
@Api(tags = { "Categories" })
public class CategoryController {

@Autowired
private CategoryService categoryService;

@RequestMapping(method=PUT, value="/categories")
@ResponseStatus(HttpStatus.CREATED)
public ResponseEntity<Void> add(
@RequestBody Category category, HttpServletRequest request) throws URISyntaxException {
final Long id = categoryService.save(category);
final HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setLocation(new URI(request.getRequestURL().toString() + "/" + id));
return new ResponseEntity<>(responseHeaders, HttpStatus.CREATED);
}
}

CategoryService.class

@Service
@Transactional
public class CategoryService {
private static Log LOG = LogFactory.getLog(CategoryService.class);

@Autowired
private CategoryRepository categoryRepository;

public Long save(Category category){
final CategoryEntity categoryEntity = new CategoryEntity(category.getName());

try {
return categoryRepository.save(categoryEntity).getId();
} catch (ClientException e) {
LOG.error("Category " + category.getName() + " exists select another name", e);
throw new NodeExistsException("Category " + category.getName() + " exists please select another name");
}
}
}

CategoryEntity.class

@NodeEntity
public class CategoryEntity {

@GraphId
private Long id;

@Index(unique=true)
private String name;

public CategoryEntity() {
}

public CategoryEntity(String name) {
this.name = name;
}

public Long getId() {
return id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

ogm.属性

driver=org.neo4j.ogm.drivers.bolt.driver.BoltDriver
URI=bolt://neo4j:password@localhost
connection.pool.size=150
indexes.auto=assert

travic-ci 日志中的最后几行

2017-05-28 08:58:34.316 DEBUG 7082 --- [nio-8080-exec-4] o.n.ogm.drivers.bolt.driver.BoltDriver   : No current transaction, starting a new one

2017-05-28 08:58:34.317 DEBUG 7082 --- [nio-8080-exec-4] o.n.ogm.drivers.bolt.driver.BoltDriver : Native transaction: org.neo4j.driver.internal.ExplicitTransaction@7e0a0bb1

2017-05-28 08:58:34.317 DEBUG 7082 --- [nio-8080-exec-4] org.neo4j.ogm.session.Neo4jSession : Thread 20: Transaction, tx id: org.neo4j.ogm.drivers.bolt.transaction.BoltTransaction@53533858

2017-05-28 08:58:34.318 DEBUG 7082 --- [nio-8080-exec-4] o.s.d.n.t.Neo4jTransactionManager : Beginning Transaction [org.neo4j.ogm.drivers.bolt.transaction.BoltTransaction@53533858] on Session [org.neo4j.ogm.session.Neo4jSession@730479f]

2017-05-28 08:58:34.318 DEBUG 7082 --- [nio-8080-exec-4] o.s.d.n.t.Neo4jTransactionManager : Found thread-bound Session [org.neo4j.ogm.session.Neo4jSession@730479f] for Neo4j OGM transaction

2017-05-28 08:58:34.318 DEBUG 7082 --- [nio-8080-exec-4] o.s.d.n.t.Neo4jTransactionManager : Participating in existing transaction

2017-05-28 08:58:34.319 DEBUG 7082 --- [nio-8080-exec-4] org.neo4j.ogm.context.EntityGraphMapper : context initialised with 0 relationships

2017-05-28 08:58:34.319 DEBUG 7082 --- [nio-8080-exec-4] org.neo4j.ogm.context.EntityGraphMapper : visiting: se.andolf.entities.CategoryEntity@7a132ac9

2017-05-28 08:58:34.319 DEBUG 7082 --- [nio-8080-exec-4] org.neo4j.ogm.context.EntityGraphMapper : se.andolf.entities.CategoryEntity@7a132ac9 has changed

2017-05-28 08:58:34.319 DEBUG 7082 --- [nio-8080-exec-4] org.neo4j.ogm.context.EntityGraphMapper : mapping references declared by: se.andolf.entities.CategoryEntity@7a132ac9

2017-05-28 08:58:34.320 INFO 7082 --- [nio-8080-exec-4] o.n.o.drivers.bolt.request.BoltRequest : Request: UNWIND {rows} as row CREATE (n:`CategoryEntity`) SET n=row.props RETURN row.nodeRef as ref, ID(n) as id, row.type as type with params {rows=[{nodeRef=-2048076489, type=node, props={name=Arms}}]}



No output has been received in the last 10m0s, this potentially indicates a stalled build or something wrong with the build itself.
Check the details on how to adjust your build configuration on: https://docs.travis-ci.com/user/common-build-problems/#Build-times-out-because-no-output-was-received

The build has been terminated

完整日志可以在这里找到: Travis-ci build log

CategoriesControllerIT.class

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = DEFINED_PORT)
public class CategoriesControllerIT {

@Test
public void shouldReturn409ConflictIfCategoryNameExists(){

final Category category = new Category("Arms");
final String id = put(category);

given()
.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
.body(category)
.when()
.put("/categories")
.then()
.statusCode(HttpStatus.CONFLICT.value());

deleteCategory(id);
}

@Test
public void shouldSaveCategory(){

final Category category = new Category("Arms");

final String header = given()
.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
.body(category)
.when()
.put("/categories")
.then()
.assertThat()
.statusCode(201)
.header("Location", is(notNullValue()))
.extract().response().getHeader("Location");

deleteCategory(UriUtil.extractLastPath(header));
}

private String put(Category category) {
try {
final String header = given().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE).body(category).put("/categories").getHeader("Location");
return UriUtil.extractLastPath(header);
} catch (Exception e) {
throw new AssertionError(e);
}
}
}

将 neo4j 作为 Docker 运行以进行 IT 测试的命令

docker run -d --name neo4j --publish=7474:7474 --publish=7687:7687 --env=NEO4J_AUTH=neo4j/password neo4j:3.2

这只是完整代码库的摘录,我已粘贴了我认为相关的内容。完整代码可以在这里找到:

Lift-app

最佳答案

在获得有关 neo4j-user slack 的帮助后,问题是驱动程序在事务关闭时关闭 session 时遇到问题。

这个问题在 neo4j-ogm 的 bolt 驱动程序 2.1.3 版本中得到了修复。

因此,将 ogm 版本从 2.1.2 升级到 2.1.3 解决了这个问题。

相关问题:Make rollback close bolt session when transaction is closed

java 驱动程序的相关问题:java-driver version 1.3.1

关于java - 在处理来自 @Index(unique=true) 的 ClientException 后,对 Neo4j 的所有后续调用都会卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44262725/

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