I am using Spring batch with spring boot for process my Csv file. When i run the application i am getting below error trace.
2018-08-27 16:23:35.694 INFO 12016 --- [nio-9004-exec-1] o.s.b.c.r.s.JobRepositoryFactoryBean : No database type set, using meta data indicating: ORACLE
2018-08-27 16:23:36.025 INFO 12016 --- [nio-9004-exec-1] o.s.b.c.l.support.SimpleJobLauncher : No TaskExecutor has been set, defaulting to synchronous executor.
2018-08-27 16:23:36.898 INFO 12016 --- [nio-9004-exec-1] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
2018-08-27 16:23:36.965 INFO 12016 --- [nio-9004-exec-1] o.s.jdbc.support.SQLErrorCodesFactory : SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
2018-08-27 16:23:37.005 ERROR 12016 --- [nio-9004-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.CannotSerializeTransactionException: PreparedStatementCallback; SQL [INSERT INTO BATCH_JOB_EXECUTION_CONTEXT (SHORT_CONTEXT, SERIALIZED_CONTEXT, JOB_EXECUTION_ID) VALUES(?, ?, ?)]; ORA-08177: can't serialize access for this transaction
; nested exception is java.sql.SQLException: ORA-08177: can't serialize access for this transaction
] with root cause
java.sql.SQLException: ORA-08177: can't serialize access for this transaction
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450) ~[ojdbc7-12.1.0.1.jar!/:12.1.0.1.0]
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399) ~[ojdbc7-12.1.0.1.jar!/:12.1.0.1.0]
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1017) ~[ojdbc7-12.1.0.1.jar!/:12.1.0.1.0]
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:655) ~[ojdbc7-12.1.0.1.jar!/:12.1.0.1.0]
at oracle.jdbc.driver.T4CTTI
After some search in google i find we have to instantiate JobRepositoryFactoryBean. so i did the same in my BatchConfiguration as below.
@Autowired
private DataSource dataSource;
@Autowired
private DataSourceTransactionManager transactionManager;
@Bean
public JobRepositoryFactoryBean jobRepository() throws SQLException{
JobRepositoryFactoryBean factoryBean = new JobRepositoryFactoryBean();
factoryBean.setDatabaseType("ORACLE");
factoryBean.setDataSource(dataSource);
factoryBean.setTransactionManager(transactionManager);
factoryBean.setIsolationLevelForCreate("ISOLATION_READ_UNCOMMITTED");
return factoryBean;
}
And the Datasource ** and **TransactionManager beans are in my DBConfiguration as below.
@Bean
public DataSource dataSource() throws SQLException
{
OracleDataSource dataSource = new OracleDataSource();
dataSource.setUser("xxxxxx");
dataSource.setPassword("xxxxx");
dataSource.setURL("xxxxx");
dataSource.setImplicitCachingEnabled(true);
dataSource.setFastConnectionFailoverEnabled(true);
return dataSource;
}
@Bean(name="transactionManager")
public PlatformTransactionManager transactionManager() throws SQLException{
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(this.dataSource());
return transactionManager;
}
Then i am getting below error
***************************
APPLICATION FAILED TO START
***************************
Description:
Field transactionManager in com.comcast.FileProcess.configuration.SprintgBatchConfiguration required a bean of type 'org.springframework.jdbc.datasource.DataSourceTransactionManager' that could not be found.
- Bean method 'transactionManager' in 'DataSourceTransactionManagerAutoConfiguration.DataSourceTransactionManagerConfiguration' not loaded because @ConditionalOnMissingBean (types: org.springframework.transaction.PlatformTransactionManager; SearchStrategy: all) found bean 'transactionManager'
Action:
Consider revisiting the conditions above or defining a bean of type 'org.springframework.jdbc.datasource.DataSourceTransactionManager' in your configuration.
Can any one help me to resolve this issues and to run my batch process.
In regards to the APPLICATION FAILED TO START
error, you need to make your transaction manager bean definition method return the actual type DataSourceTransactionManager
and not PlatformTransactionManager
:
@Bean(name="transactionManager")
public DataSourceTransactionManager transactionManager() throws SQLException{
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(this.dataSource());
return transactionManager;
}
In regards to the java.sql.SQLException: ORA-08177: can't serialize access for this transaction
error, it looks like the IsolationLevelForCreate
is still ISOLATION_SERIALIZABLE
and your database is unable to serialize the transaction. This is probably due to your job repository which is not taken into account. I would make the jobRepository
method return the job repository itself (as in the example here) and not the factory bean:
@Bean
public JobRepository jobRepository() throws SQLException{
JobRepositoryFactoryBean factoryBean = new JobRepositoryFactoryBean();
factoryBean.setDatabaseType("ORACLE");
factoryBean.setDataSource(dataSource);
factoryBean.setTransactionManager(transactionManager);
factoryBean.setIsolationLevelForCreate("ISOLATION_READ_UNCOMMITTED");
return factoryBean.getObject();
}
This way, your job repository will be correctly configured with ISOLATION_READ_UNCOMMITTED
and your database will not try to serialize transactions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With