2016-02-26 1 views
1

Сначала заявление о проблеме: Я использую Spring-Batch в моей среде DEV. Когда я перемещаю код в производственную среду, у меня возникает проблема. В моей среде DEV Spring-Batch может создавать свои таблицы данных транзакций на нашем сервере баз данных DB2 без проблем. Это не вариант, когда мы переходим к PROD, поскольку это работа только для чтения.Spring Batch - Как предотвратить пакет от хранения транзакций в БД

Покушение решение:

Поиск Stack Overflow Я нашел объявление: Spring-Batch without persisting metadata to database?

который звучал идеально, поэтому я добавил

@Bean 
public ResourcelessTransactionManager transactionManager() { 
    return new ResourcelessTransactionManager(); 
} 

@Bean 
public JobRepository jobRepository(ResourcelessTransactionManager transactionManager) throws Exception { 
    MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean = new MapJobRepositoryFactoryBean(transactionManager); 
    mapJobRepositoryFactoryBean.setTransactionManager(transactionManager); 

    return mapJobRepositoryFactoryBean.getObject(); 
} 

Я также добавил его к моему работодателю по телефону .reporitory (jobRepository).

Но я получаю

Caused by: java.lang.NullPointerException: null 
    at  org.springframework.batch.core.repository.dao.MapJobExecutionDao.synchronizeStatus(MapJobExecutionDao.java:158) ~[spring-batch-core-3.0.6.RELEASE.jar:3.0.6.RELEASE] 

Так что я не знаю, что делать здесь. Я новичок в «Весне», поэтому я учу себя как иду. Я открыт для других решений, таких как база данных в памяти, но я не смог заставить их работать. Мне не нужно сохранять информацию о состоянии или сеансе между запусками, но запрос базы данных, который я запускаю, будет возвращать около миллиона строк, поэтому мне нужно будет получить это в кусках.

Любые предложения или помощь были бы весьма полезны.

ответ

0

Ниже, кажется, сделали эту работу для меня:

@Bean 
public DataSource dataSource() {   

    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); 
    EmbeddedDatabase db = builder 
     .setType(EmbeddedDatabaseType.HSQL) 
     .build(); 
    return db; 
} 

Теперь Spring не создает таблицы в нашей производственной базе данных, и, когда виртуальная машина выходит из состояния теряется, поэтому ничего не кажется, висит вокруг.

UPDATE: Приведенный выше код вызвал ошибки параллельности для нас.Мы обратились это, отказавшись от EmbeddedDatabaseBuilder и объявить HSQLDB этот путь вместо этого:

@Bean 
    public BasicDataSource dataSource() { 
     BasicDataSource dataSource = new BasicDataSource(); 
      dataSource.setDriverClassName("org.hsqldb.jdbcDriver"); 
      dataSource.setUrl("jdbc:hsqldb:mem:testdb;sql.enforce_strict_size=true;hsqldb.tx=mvcc"); 
      dataSource.setUsername("sa"); 
      dataSource.setPassword(""); 
     return dataSource; 
    } 

Основное отличие заключается в том, что мы можем указать MVCC (многовариантность управления параллелизмом) в строке подключения, которая решает эту проблему.

+0

это не потокобезопасный. Если два потока одновременно пытаются получить доступ к одному и тому же заданию, будет исключение доступа к параллельному потоку – Harish

+0

Как бы вы изменили его на потокобезопасность, соблюдая ограничения, над которыми я работаю? – VydorScope

+0

Я использовал хранилище на основе карты – Harish

0

Это не отвечает на ваш вопрос напрямую, но это нехорошее решение; предполагается, что репозиторий на основе карт будет использоваться только для тестирования. Он будет расти в памяти на неопределенный срок.

Я предлагаю вам использовать встроенную базу данных, такую ​​как sqlite. Основная проблема при использовании отдельной базы данных для метаданных задания заключается в том, что вы должны затем координировать транзакции между двумя используемыми вами базами данных (чтобы состояние метаданных соответствовало состоянию данных), но поскольку кажется, что вы даже не пишете в основной базе данных, это, вероятно, не будет проблемой для вас.

+0

Почему бы ему расти в памяти до бесконечности? После завершения работы программа java завершает работу и не будет запускаться снова до следующего дня. Все, что в памяти должно быть очищено при выходе из программы Java. На следующий день, когда он запустится, должна быть новая база данных памяти, созданная при вызове java-программы нашим планировщиком. Мне не нужно никакого состояния, чтобы упорствовать между прогонами. – VydorScope

+0

@VydorScope Ну, он растет бесконечно до выхода JVM или завершения контекста. Если это так, как вы запускаете пакет Spring, это не проблема. Но есть и другие проблемы (которые могут или не могут применяться к вам), например, тот факт, что реализация карты не участвует в транзакциях. – Artefacto

+0

JVM будет закрыт, и контекст будет закрыт после завершения задания. – VydorScope

0

Вы можете легко использовать базу данных в памяти (например, H2 или HSQL). Примеры этого можно найти здесь: http://www.mkyong.com/spring/spring-embedded-database-examples/.

Что касается карт спинок хранилища заданий, он обеспечивает method, чтобы очистить его содержимое:

public void clear() 

Convenience method to clear all the map DAOs globally, removing all entities. 

Имейте в виде, что карта на основе хранилище работы не подходит для использования в секционированных шагах и других многосторонних -threading.

+0

Я делаю многопоточность. У меня есть несколько шагов, которые я запускаю параллельно. Что вы подразумеваете под «не подходит для использования» в этом случае? – VydorScope

+1

Я недавно спросил об этом, [здесь] (http://stackoverflow.com/questions/35484563/spring-batch-thread-safe-map-job-repository). В документе явно указано, что хранилище заданий с поддержкой карт не должно использоваться. –

3

Добавить эту фасоль AppClass

@Bean 
public PlatformTransactionManager transactionManager() { 
    return new ResourcelessTransactionManager(); 
} 


@Bean 
public JobExplorer jobExplorer() throws Exception { 
    MapJobExplorerFactoryBean jobExplorerFactory = new MapJobExplorerFactoryBean(mapJobRepositoryFactoryBean()); 
    jobExplorerFactory.afterPropertiesSet(); 
    return jobExplorerFactory.getObject(); 
} 

@Bean 
public MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean() { 
    MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean = new MapJobRepositoryFactoryBean(); 
    mapJobRepositoryFactoryBean.setTransactionManager(transactionManager()); 
    return mapJobRepositoryFactoryBean; 
} 

@Bean 
public JobRepository jobRepository() throws Exception { 
    return mapJobRepositoryFactoryBean().getObject(); 
} 

@Bean 
public JobLauncher jobLauncher() throws Exception { 
    SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher(); 
    simpleJobLauncher.setJobRepository(jobRepository()); 
    return simpleJobLauncher; 
} 
Смежные вопросы