Как настроить два менеджера транзакций? - PullRequest
0 голосов
/ 04 сентября 2018

Я работаю над приложением Spring, в котором уже настроен менеджер транзакций.

В классе конфигурации он уже настроил чтение диспетчера сущностей из файла persistence.xml, а затем настроил JpaTransactionManager.

Мне необходимо создать реализацию Spring Batch, и проблема в том, что, как я узнал из разных постов, при использовании аннотации @EnableBatchProcessing кажется, что зарегистрирован второй менеджер транзакций, и я не могу сохранить данные внутри моего тасклеты.

Можно ли использовать два менеджера транзакций или настроить мое приложение таким образом, чтобы я смог сохранить свои данные?

Не могли бы вы предоставить пример кода?

Заранее спасибо.

EDIT:

Это класс конфигурации приложения, который уже существует в приложении:

@Configuration
@ComponentScan({
    ...
})
@EnableJpaRepositories("...")
@EnableTransactionManagement
@EnableJpaAuditing
@Import({SecurityConfig.class})
@PropertySource("classpath:application.properties")
public class ApplicationConfig {

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setPersistenceXmlLocation("classpath:/META-INF/persistence.xml");
        return factory;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
        return transactionManager;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

это мой пакетный конфиг:

@Configuration
@EnableBatchProcessing
public class BatchConfig {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Autowired
    @Qualifier("entityManagerFactory")
    private LocalEntityManagerFactoryBean batchEntityManagerFactory;


}

из которого я получаю:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.orm.jpa.LocalEntityManagerFactoryBean com.xxx.xxx.xxx.configuration.BatchConfig.batchEntityManagerFactory; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.orm.jpa.LocalEntityManagerFactoryBean] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.sp
ringframework.beans.factory.annotation.Qualifier(value=entityManagerFactory)}

РЕДАКТИРОВАТЬ 2: Вот что я сделал:

@EnableJpaRepositories("xxx")
@Configuration
@EnableBatchProcessing
@PropertySource("classpath:application.properties")
public class BatchConfig {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Autowired
    private ReportReaderProcessor reportReaderProcessor;

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setPersistenceXmlLocation("classpath:/META-INF/persistence.xml");
        return factory;
    }

    @Bean
    public BatchConfigurer batchConfigurer() {
        return new DefaultBatchConfigurer() {
            @Override
            public PlatformTransactionManager getTransactionManager() {
                JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
                jpaTransactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
                return jpaTransactionManager;
            }
        };
    }
    @Bean
    public JobRepository jobRepository() throws Exception {
        MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
        factory.setTransactionManager(batchConfigurer().getTransactionManager());
        return (JobRepository) factory.getObject();
    }

    @Bean
    public SimpleJobLauncher simpleJobLauncher() throws Exception {
        SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
        simpleJobLauncher.setJobRepository(jobRepository());
        return simpleJobLauncher;
    }

    @Bean
    public Step readReports() {
        return steps
                .get("readReports")
                .tasklet(reportReaderProcessor)
                .build();
    }

    @Bean
    public Job reportJob() {
        return jobs
                .get("submitReportJob")
                .start(readReports())
                .build();
    }
}

но теперь я получаю другую ошибку:

15:47:23,657 ERROR [stderr] (pool-36-thread-1) org.springframework.transaction.InvalidIsolationLevelException: DefaultJpaDialect does not support custom isolation levels due to limitations in standard JPA. Specific arrangements may be implemented in custom JpaDialect variants.

1 Ответ

0 голосов
/ 04 сентября 2018

Здесь есть открытый вопрос для этого случая: https://jira.spring.io/browse/BATCH-2294, который исправлен в версии 4.1.0.M3. Чтобы использовать настраиваемый менеджер транзакций, вам необходимо указать BatchConfigurer в контексте приложения, например:

@Bean
public BatchConfigurer batchConfigurer() {
    return new DefaultBatchConfigurer() {
        @Override
        public PlatformTransactionManager getTransactionManager() {
           return new MyTransactionManager();
        }
    };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...