首页 > 解决方案 > 无法将此事务的访问序列化并隔离为 ISOLATION_READ_UNCOMMITTED

问题描述

使用 spring-batch,我有 2 个数据源:一个用于 spring 批处理调用centralDataSource,一个用于业务调用localDataSource

我已将隔离级别设置为 ISOLATION_READ_UNCOMMITTED 以避免并发事务出现如下问题。

@Bean
public Job myJob(Step firstStep,
                     Step secondStep,
                     JobCompletionNotificationListener listener,
                     JobRepository customJobRepository) {
    return jobBuilderFactory.get("my-job")
                           .repository(customJobRepository)
                           .listener(listener)
                           .incrementer(new RunIdIncrementer())
                           .start(firstStep)
                           .next(secondStep)
                           .build();
}

@Bean
public JobRepository customJobRepository(
        @Qualifier("centralDataSource") DataSource centralDataSource,
        @Qualifier("centralTransactionManager") PlatformTransactionManager centralTransactionManager)
            throws Exception {
    JobRepositoryFactoryBean factoryBean = new JobRepositoryFactoryBean();
    factoryBean.setDatabaseType("ORACLE");
    factoryBean.setDataSource(centralDataSource);
    factoryBean.setTransactionManager(centralTransactionManager);
    factoryBean.setIsolationLevelForCreate("ISOLATION_READ_UNCOMMITTED");
    return factoryBean.getObject();
}

我还有Application run failedSQLException: ORA-08177: can’t serialize access for this transaction

我不明白为什么。甚至没有2个并发的 spring 批处理作业同时运行。作业是按顺序运行的,为什么会发生这种情况,我该如何解决?

谁能帮我 ?

标签: oraclespring-batch

解决方案


我不知道 Spring 以及它如何更改事务隔离级别,但是:

一、Oracle数据库不支持READ_UNCOMMITTED隔离级别:

alter session set isolation_level=read_uncommitted
                                  *
ERROR at line 1:
ORA-02183: valid options: ISOLATION_LEVEL { SERIALIZABLE | READ COMMITTED }

其次,如果您有 ORA-8177,则表示您正在使用 SERIALIZABLE 隔离级别。

$ oerr ora 8177
08177, 00000, "can't serialize access for this transaction"
// *Cause:   Encountered data changed by an operation that occurred after
//           the start of this serializable transaction.
// *Action:  In read/write transactions, retry the intended operation or
//           transaction.

您需要检查 Spring 运行了哪些 ALTER SESSION 语句来更改隔离级别。


推荐阅读