ORA-08177:无法使用 oracle 在 Spring 批处理中序列化对此事务的访问

问题描述 投票:0回答:1

我正在使用弹簧批。我有超过 10 个批处理进程运行相同的数据库连接。我已经使用春季调度运行了这些批次。但它显示以下错误:

org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [INSERT into BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) values (?, ?, ?, ?)]; SQL state [72000]; error code [8177]; ORA-08177: can't serialize access for this transaction

at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1539)
        ........
Caused by: java.sql.SQLException: ORA-08177: can't serialize access for this transaction
        .....
 Caused by: Error : 8177, Position : 0, Sql = INSERT into BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) values (:1 , :2 , :3 , :4 ), OriginalSql = INSERT into BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) values (?, ?, ?, ?), Error Msg = ORA-08177: can't serialize access for this transaction

     at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:636)
        ... 53 more

我在下面配置了 Spring 批处理,如下所示:

  1. 应用程序属性:

    spring.datasource.url=myurl
    spring.datasource.username=mydbName
    spring.datasource.password=myPassword
    spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
    
    spring.batch.job.enabled=true
    spring.batch.job.chunk.size=10
    
    
    # 0 */2 * * * ? --> 2 minutes
    batch-schduled-time=0 */2 * * * ?
    
  2. 我的批处理作业

    @Component
    @RequiredArgsConstructor
    @Slf4j
    public class MyJob {
    
       private final MyTrxSummaryRepo approvedTrxSummaryRepo;
       private final MyApprovedTransactionRepo corpApprovedTransactionRepo;
    
       private final MyTransactionViewRepo allApprovedTransactionViewRepo;
    
    
       private final ProcessorStep1 batchProcessorStep1;
       private final WriterStep1 batchWriterStep1;
    
    
    
       private final PlatformTransactionManager transactionManager;
       private final JobRepository jobRepository;
    
    
    
       @Value("${spring.batch.job.chunk.size}")
       private Integer chunkSize;
    
    
    
       public Job createEft(){
    
           String id = UUID.randomUUID().toString();
    
           return new JobBuilder(id, jobRepository)
                   .incrementer(new RunIdIncrementer())
                   .start(step1())
                   .build();
    
       }
    
    
    
       private Step step1(){
    
           return new StepBuilder("step1", jobRepository)
                   .<MyTrxSummery,MyTrxSummery> chunk(chunkSize, transactionManager)
                   .reader(new ReaderStep1(approvedTrxSummaryRepo,corpApprovedTransactionRepo))
                   .processor(batchProcessorStep1)
                   .writer(batchWriterStep1)
                   .build();
       }
    
    
    
    
       }
    
  3. BatchBean

     @Configuration
     public class BatchBean {
        @Bean
        public ProcessorStep1 batchProcessorStep1() {
            return new ProcessorStep1();
        }
    
        @Bean
        public WriterStep1 batchWriterStep1() {
            return new WriterStep1();
        }
    
      }
    
  4. MyTrxSummery 实体和存储库:

    @Entity
    @Table(name = "mySummeryTb")
    @Data
    @Setter
    @NoArgsConstructor
    @AllArgsConstructor
    public class MyTrxSummery {
        @Id
        @Column(name = "TRANSACTION_REFERENCE")
        private String transactionReference;
      .........
    
    }
    
    @Repository
    public interface MyTrxSummaryRepo extends JpaRepository<MyTrxSummery, Long> {
    
        @Query("myquery.....")
        List<MyTrxSummery> getAllTransaction();
    
        MyTrxSummery findByTransactionReference(String transactionReference);
    
        @Modifying
        @Query(" update.....")
        public void updateApprovedTrxSummeriesByTransactionReference(String transactionReference);
    
    
        @Modifying
        @Query(" update......")
        public void updateSegmentedTransaction(String transactionReference);
    
    
    }
    
  5. MyTransaction 实体和存储库::

    @Entity
    @Table(name = "CORP_APPROVED_TRANSACTION")
    @Data
    @Setter
    @NoArgsConstructor
    @AllArgsConstructor
    public class CorpApprovedTransaction {
    
       @Id
       @Column(name = "TRANSACTION_ID")
       private Long transactionId;
       ............
     }
    

    @Transactional
    @Repository
    public interface MyTransactionRepo extends JpaRepository<MyTransaction, Long> {
    
       @Query("select....")
       List<MyTransaction> findSegmentedTransaction(String transactionReference);
    
        @Modifying
        @Query("update ..")
        public void updateMyTransactionByTransactionReference(String transactionReference);
    
    
     }
    
  6. 读取器步骤1、处理器步骤1和写入器步骤1

       @Slf4j
    public class ReaderStep1 implements ItemReader<MyTrxSummery> {
    
       private Iterator<MyTrxSummery> iterator;
    
       public ReaderStep1(MyTrxSummaryRepo myTrxSummaryRepo, MyTransactionRepo corpApprovedTransactionRepo) {
    
           List<MyTrxSummery> list = myTrxSummaryRepo.getAllTransaction();
           if(!list.isEmpty()){
    
               this.iterator = list.iterator();
           }
         }
       @Override
       public MyTrxSummery read() {
    
           return (iterator != null && iterator.hasNext()) ? iterator.next() : null;
        }  
      }
    

     @Slf4j
     public class ProcessorStep1 implements ItemProcessor<MyTrxSummery, MyTrxSummery> {
    
    
    
       @Autowired
       private MyTrxSummaryRepo approvedTrxSummaryRepo;
    
       @Autowired
       private MyTransactionRepo corpApprovedTransactionRepo;
    
        @Override
       public MyTrxSummery process(MyTrxSummery item) throws Exception {
            ......
         }
    
        }
    

    @Slf4j
    public class WriterStep1 implements ItemWriter<MyTrxSummery> {
    
       @Override
       public void write(Chunk<? extends MyTrxSummery> chunk) {
          ........
          }
    
        }
    
  7. ScheduledJobBean

    @Component
    @Slf4j
    public class ScheduledJobBean {
    
       @Autowired
       JobLauncher jobLauncher;
    
       @Autowired
       MyJob eftJob;
    
       @Scheduled(cron = "${batch-schduled-time}")
       public void perform() throws Exception
       {
    
          try {
               JobExecution execution = jobLauncher.run(eftJob.createEft(), new JobParameters());
    
           }catch (Exception ex) {
               ex.printStackTrace();
           }
    
        }
     }
    

我的代码有什么问题...

请帮我解决问题......

oracle spring-batch
1个回答
0
投票

在 ORACLE 支持网站上找到:

“使用可序列化事务并发插入到带有索引的表中 可能会导致事务尝试重新读取的索引拆分并导致错误 ORA-08177

修复: 插入较少数量的行(例如更频繁地提交)

-或-

捕获应用程序中的错误代码并重试操作

-或-

这可以通过在正常表创建期间实现“行依赖关系”来解决。”

© www.soinside.com 2019 - 2024. All rights reserved.