Spring Batch和Neo4j:事务同步未激活

时间:2016-08-28 13:08:41

标签: spring-data spring-batch spring-data-neo4j

我使用Spring Batch处理一些资源,并希望将分析结果放入Neo4j数据库。作业存储库不应该在Neo4j中,而只需使用嵌入式HSQL DB。当我运行我的工作时,我收到以下错误:

2016-08-28 14:37:59.215  INFO 1934 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=job]] launched with the following parameters: [{run.id=1, -spring.output.ansi.enabled=always}]
2016-08-28 14:37:59.254  INFO 1934 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step]
2016-08-28 14:37:59.707  INFO 1934 --- [           main] o.n.o.drivers.http.request.HttpRequest   : Thread 1: POST http://neo4j:graphdb@localhost:7474/db/data/transaction HTTP/1.1
2016-08-28 14:37:59.808  INFO 1934 --- [           main] o.n.o.drivers.http.request.HttpRequest   : Thread 1: DELETE http://localhost:7474/db/data/transaction/18 HTTP/1.1
2016-08-28 14:37:59.819 ERROR 1934 --- [           main] o.s.batch.core.step.AbstractStep         : Encountered an error executing step step in job job

java.lang.IllegalStateException: Transaction synchronization is not active
    at org.springframework.transaction.support.TransactionSynchronizationManager.registerSynchronization(TransactionSynchronizationManager.java:291) ~[spring-tx-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:389) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]

我尝试明确地为作业存储库和整个作业存储库配置事务管理器,但错误仍然相同。产生此错误的缩减项目如下所示:

BatchConfiguration.java

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Step step() {
        return stepBuilderFactory.get("step").tasklet(new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
                return null;
            }
        }).build();
    }

    @Bean
    public Job job(Step step) throws Exception {
        return jobBuilderFactory.get("job").incrementer(new RunIdIncrementer()).start(step).build();
    }

}

的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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-batch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-neo4j</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

输出

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.0.RELEASE)

2016-08-28 14:37:55.032  INFO 1934 --- [           main] com.example.DemoApplication              : Starting DemoApplication on manuels-macbook-air.home with PID 1934 (/Users/maenu/Development/university/masters/null-infection/demo/target/classes started by maenu in /Users/maenu/Development/university/masters/null-infection/demo)
2016-08-28 14:37:55.037  INFO 1934 --- [           main] com.example.DemoApplication              : No active profile set, falling back to default profiles: default
2016-08-28 14:37:55.138  INFO 1934 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@e70f13a: startup date [Sun Aug 28 14:37:55 CEST 2016]; root of context hierarchy
2016-08-28 14:37:55.983  INFO 1934 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'transactionManager' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration; factoryMethodName=transactionManager; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/batch/core/configuration/annotation/SimpleBatchConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=neo4jDataSourceConfiguration; factoryMethodName=transactionManager; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/example/Neo4jDataSourceConfiguration.class]]
2016-08-28 14:37:56.483  WARN 1934 --- [           main] o.s.c.a.ConfigurationClassEnhancer       : @Bean method ScopeConfiguration.stepScope is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.
2016-08-28 14:37:56.502  WARN 1934 --- [           main] o.s.c.a.ConfigurationClassEnhancer       : @Bean method ScopeConfiguration.jobScope is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.
2016-08-28 14:37:56.586  INFO 1934 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'neo4jDataSourceConfiguration' of type [class com.example.Neo4jDataSourceConfiguration$$EnhancerBySpringCGLIB$$8278a1ab] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2016-08-28 14:37:56.587  INFO 1934 --- [           main] o.s.d.neo4j.config.Neo4jConfiguration    : Initialising PersistenceExceptionTranslationPostProcessor
2016-08-28 14:37:57.068  INFO 1934 --- [           main] o.s.d.neo4j.config.Neo4jConfiguration    : Initialising Neo4jTransactionManager
2016-08-28 14:37:57.069  INFO 1934 --- [           main] o.s.d.neo4j.config.Neo4jConfiguration    : Initialising Neo4jSession
2016-08-28 14:37:57.091  INFO 1934 --- [           main] o.neo4j.ogm.metadata.ClassFileProcessor  : Starting Post-processing phase
2016-08-28 14:37:57.091  INFO 1934 --- [           main] o.neo4j.ogm.metadata.ClassFileProcessor  : Building annotation class map
2016-08-28 14:37:57.091  INFO 1934 --- [           main] o.neo4j.ogm.metadata.ClassFileProcessor  : Building interface class map for 0 classes
2016-08-28 14:37:57.094  INFO 1934 --- [           main] o.neo4j.ogm.metadata.ClassFileProcessor  : Post-processing complete
2016-08-28 14:37:57.094  INFO 1934 --- [           main] o.neo4j.ogm.metadata.ClassFileProcessor  : 0 classes loaded in 14 milliseconds
2016-08-28 14:37:57.132  INFO 1934 --- [           main] org.neo4j.ogm.service.DriverService      : Using driver: org.neo4j.ogm.drivers.http.driver.HttpDriver
2016-08-28 14:37:57.414  INFO 1934 --- [           main] o.s.d.neo4j.mapping.Neo4jMappingContext  : Neo4jMappingContext initialisation completed
2016-08-28 14:37:57.435  INFO 1934 --- [           main] o.s.d.neo4j.config.Neo4jConfiguration    : Initialising PersistenceExceptionTranslator
2016-08-28 14:37:57.440  INFO 1934 --- [           main] o.s.d.neo4j.config.Neo4jConfiguration    : Initialising PersistenceExceptionTranslationInterceptor
2016-08-28 14:37:58.418  INFO 1934 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executing SQL script from class path resource [org/springframework/batch/core/schema-hsqldb.sql]
2016-08-28 14:37:58.437  INFO 1934 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executed SQL script from class path resource [org/springframework/batch/core/schema-hsqldb.sql] in 19 ms.
2016-08-28 14:37:58.844  INFO 1934 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2016-08-28 14:37:58.871  INFO 1934 --- [           main] o.s.b.a.b.JobLauncherCommandLineRunner   : Running default command line with: [--spring.output.ansi.enabled=always]
2016-08-28 14:37:58.890  INFO 1934 --- [           main] o.s.b.c.r.s.JobRepositoryFactoryBean     : No database type set, using meta data indicating: HSQL
2016-08-28 14:37:59.116  INFO 1934 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : No TaskExecutor has been set, defaulting to synchronous executor.
2016-08-28 14:37:59.215  INFO 1934 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=job]] launched with the following parameters: [{run.id=1, -spring.output.ansi.enabled=always}]
2016-08-28 14:37:59.254  INFO 1934 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step]
2016-08-28 14:37:59.707  INFO 1934 --- [           main] o.n.o.drivers.http.request.HttpRequest   : Thread 1: POST http://neo4j:graphdb@localhost:7474/db/data/transaction HTTP/1.1
2016-08-28 14:37:59.808  INFO 1934 --- [           main] o.n.o.drivers.http.request.HttpRequest   : Thread 1: DELETE http://localhost:7474/db/data/transaction/18 HTTP/1.1
2016-08-28 14:37:59.819 ERROR 1934 --- [           main] o.s.batch.core.step.AbstractStep         : Encountered an error executing step step in job job

java.lang.IllegalStateException: Transaction synchronization is not active
    at org.springframework.transaction.support.TransactionSynchronizationManager.registerSynchronization(TransactionSynchronizationManager.java:291) ~[spring-tx-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:389) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133) ~[spring-tx-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:81) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:374) ~[spring-batch-infrastructure-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144) ~[spring-batch-infrastructure-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:392) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:135) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:306) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) [spring-core-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:128) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_05]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_05]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_05]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_05]
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) [spring-aop-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) [spring-aop-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) [spring-aop-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) [spring-aop-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at com.sun.proxy.$Proxy44.run(Unknown Source) [na:na]
    at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.execute(JobLauncherCommandLineRunner.java:216) [spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.executeLocalJobs(JobLauncherCommandLineRunner.java:233) [spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.launchJobFromProperties(JobLauncherCommandLineRunner.java:125) [spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.run(JobLauncherCommandLineRunner.java:119) [spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:782) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:769) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at com.example.DemoApplication.main(DemoApplication.java:10) [classes/:na]

2016-08-28 14:37:59.829  INFO 1934 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=job]] completed with the following parameters: [{run.id=1, -spring.output.ansi.enabled=always}] and the following status: [FAILED]
2016-08-28 14:37:59.833  INFO 1934 --- [           main] com.example.DemoApplication              : Started DemoApplication in 5.44 seconds (JVM running for 6.138)
2016-08-28 14:37:59.838  INFO 1934 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@e70f13a: startup date [Sun Aug 28 14:37:55 CEST 2016]; root of context hierarchy
2016-08-28 14:37:59.841  INFO 1934 --- [       Thread-2] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown

我注意到了这一行

2016-08-28 14:37:55.983  INFO 1934 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'transactionManager' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration; factoryMethodName=transactionManager; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/batch/core/configuration/annotation/SimpleBatchConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=neo4jDataSourceConfiguration; factoryMethodName=transactionManager; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/example/Neo4jDataSourceConfiguration.class]]

看起来很可疑。

为什么我会收到此错误以及如何解决此问题,以便将spring-data-neo4j集成到spring-batch

2 个答案:

答案 0 :(得分:1)

Spring批处理使用基于sql的db来存储它的作业和执行。

通过创建一个将sql DataSource和Neo4jTransactionManager链接在一起的PlatformTransactionManager,我们可以使它工作。

@Configuration课程中添加以下内容

import org.neo4j.ogm.session.Session;
import javax.sql.DataSource;

import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.data.transaction.ChainedTransactionManager;

import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.data.neo4j.transaction.Neo4jTransactionManager;


// The Neo4j database session
@Autowired
public Session session;

// The JDBC data source
@Autowired
public DataSource dataSource;

@Bean
public PlatformTransactionManager chainedTransactionManager() {
    ChainedTransactionManager chainedTransactionManager = new ChainedTransactionManager(
        new DataSourceTransactionManager(dataSource),
        new Neo4jTransactionManager(session)
    );

    return chainedTransactionManager;
}

答案 1 :(得分:0)

我使用spring boot 1.4.0时遇到了同样的错误,而是尝试批量处理嵌入式neo4j服务器。我开始工作的方法是从Neo4jDataAutoConfiguration.class中排除@EnableAutoConfiguration。这对我来说很好,因为我手动创建bean来获取GraphDatabaseService。作为一种解决方法,我想你可以尝试做同样的事情但是在这里提到方法:http://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#_configuring_the_http_driver

希望它有所帮助。