接收ORA-08177:启动Spring应用程序时无法对此事务进行序列化访问

时间:2017-06-06 16:41:12

标签: java spring oracle spring-boot spring-batch

我最近在我的项目中出现了一个奇怪的问题,我似乎无法确定其来源,并且想知道那些精通Spring和Oracle的人是否可以对这个顽固的bug有所了解。

简而言之,当我开始工作时,它会在我的工作配置中执行第一步,然后每次输出以下内容。

2017-06-06 12:22:38.341  INFO 10776 --- [ask-scheduler-3] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
2017-06-06 12:22:38.360  INFO 10776 --- [ask-scheduler-3] o.s.jdbc.support.SQLErrorCodesFactory    : SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana]
2017-06-06 12:22:38.412 ERROR 10776 --- [ask-scheduler-3] o.s.integration.handler.LoggingHandler   : 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

    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:267)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:870)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:931)
    at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.persistSerializedContext(JdbcExecutionContextDao.java:233)
    at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.saveExecutionContext(JdbcExecutionContextDao.java:175)
    at org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.java:146)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.batch.core.repository.support.AbstractJobRepositoryFactoryBean$1.invoke(AbstractJobRepositoryFactoryBean.java:172)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
    at com.sun.proxy.$Proxy78.createJobExecution(Unknown Source)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:125)
    at org.autodatacorp.dpt.importer.costimport.etl.scheduling.CostImportJobRunnable.launchCostImportJob(CostImportJobRunnable.java:64)
    at org.autodatacorp.dpt.importer.costimport.etl.scheduling.CostImportJobRunnable.run(CostImportJobRunnable.java:48)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.sql.SQLException: ORA-08177: can't serialize access for this transaction

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:225)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:53)
    at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:943)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1150)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:4798)
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:4875)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1361)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:877)
    at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:870)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:633)
    ... 32 more

这项工作将继续进行,但会不断反复出现这种错误。

我试图启用logback.xml来尝试获取有关正在发生的事情的更多信息,但似乎在执行时挂起作业进程。为应用程序启用调试模式会提供相同的错误,而无需额外的洞察力。我已经尝试使用Oracle的本地实例和远程,错误消息或频率没有区别。将oracle-batch.properties中的batch.isolationlevel设置为READ_COMMITED和ISOLATION_SERIALIZABLE不会解决问题。我已经验证我今天是我们亚马逊实例的唯一用户,否定了多个用户以某种方式访问​​数据库时发生冲突的可能性,并且已经验证我正在使用的代码确实构建没有错误。我还验证了在DatabaseConfiguration类中设置了@EnableTransaction注释。

正在使用最新版本的Spring Batch和Boot,而Oracle实例都使用Oracle 12c。其他应用程序可以使用相同的登录凭据进行正常连接(当我测试此应用程序时,它们没有连接到数据库)。当然,Spring批处理表确实存在于DB中,并且可以访问用于登录数据库的用户

简而言之,我已经没有可能性,因为这是什么原因以及如何让它变得快乐。有人遇到过这个问题,有什么建议吗?

编辑:根据要求,作业配置

@Bean
public Job sampleJob(@Qualifier("stepOne") Step stepOne,
                             @Qualifier("stepTwo") Step stepTwo,
                             @Qualifier("stepThree") Step stepThree,
                             @Qualifier("stepFour") Step stepFour,
                             @Qualifier("stepFive") Step stepFive,
                             @Qualifier("stepSix") Step stepSix,
                             @Qualifier("listener") CustomJobListener listener
) {

    LOGGER.info("Starting Job");

    return jobBuilderFactory.get("Importing Data")
                            .incrementer(new RunIdIncrementer())
                            .listener(listener)
                            .flow(stepOne)

                            .next(stepTwo)
                            .from(stepTwo).on(Constants.STEP_EXIT_STATUS_CONTINUE)
                            .to(stepThree)
                            .from(stepTwo).on(Constants.STEP_EXIT_STATUS_COMPLETED).end()
                            .from(stepThree)

                            .next(stepFour)
                            .from(stepFour).on(Constants.STEP_EXIT_STATUS_CONTINUE)
                            .to(transformingCostImportData)
                            .from(stepFour).on(Constants.STEP_EXIT_STATUS_COMPLETED).end()
                            .from(transformingCostImportData)

                            .next(stepFive)
                            .next(stepSix)
                            .next(stepTwo)
                            .build()
                            .build();
}

0 个答案:

没有答案