簡體   English   中英

如何在Spring Batch塊中管理較短的事務?

[英]How to manage shorter transaction inside Spring Batch chunk?

我在使用Spring Batch時遇到問題,似乎找不到解決方案。

因此,我已經批量處理了一些項目(大小為10)。 我還具有該批次使用的事務管理器,用於在每個塊之后保留已處理的項目。

但是...我還想實時保持這些項目的某些進度狀態。 因此,在處理項目之前,我想保存一個狀態,指出該項目正在進行中。

而且我似乎找不到解決該問題的解決方案。 我嘗試了以下解決方案:

  1. 如果僅使用事務性注釋對狀態管理器服務進行注釋,則在整個塊處理之后將提交狀態。
  2. 如果我在注釋中添加REQUIRES_NEW作為傳播級別,則可以使用...但是批處理以某種死鎖結束(我讀到這是REQUIRES_NEW的常見問題)。
  3. 所以我最后的猜測是添加第二個事務管理器(在同一數據源上)並在狀態管理器服務上使用它...但是我得到了與解決方案#1相同的結果(這對我來說似乎很奇怪,因為我期望從該經理可以獨立於大塊交易而行動)。

有人遇到過這個問題嗎?

編輯:這是我的配置,故意簡化:

類DbConfiguration:

@Configuration
public class DbConfiguration {
    @Bean
    @Primary
    public JpaTransactionManager transactionManager() throws Exception {
        final JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
        jpaTransactionManager.setEntityManagerFactory(entityManagerFactory());
        jpaTransactionManager.afterPropertiesSet();
        return jpaTransactionManager;
    }
}

類JobConfiguration:

@Configuration
@Import(DbConfiguration.class)
@EnableTransactionManagement
public class JobConfiguration {
    @Autowired
    private EntityManagerFactory entityManagerFactory;

    @Bean
    public Job jobDefinition() {
        return jobBuilderFactory
            .get(JOB_NAME)
            .start(step())
            .build();
    }

    @Bean
    public Step step() {
        return stepBuilderFactory
            .get(STEP_NAME)
            .<Object, Object>chunk(COMMIT_INTERVAL)
                    .reader(reader())
                    .processor(processor())
                    .writer(writer())
            .build();
    }

    @Bean
    public PlatformTransactionManager statusTransactionManager() {
        final JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
        jpaTransactionManager.setEntityManagerFactory(entityManagerFactory);
        jpaTransactionManager.afterPropertiesSet();
        return jpaTransactionManager;
    }
}

類StatusManagerServiceImpl:

@Transactional("statusTransactionManager")
public class StatusManagerServiceImpl implements StatusManagerService {
    ...
}

實現此目的的一種方法是使用Spring TransactionTemplate,如下所示:

@Service
public class StatusManagerServiceImpl implements StatusManagerService {
    @Autowired
    private PlatformTransactionManager transactionManager;

    public separateTransactionMethod() {
        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                // Do something here that will be committed right away.
            }
        });
    }
}

如果有返回結果,則可以使用新的TransactionCallback。 然后execute方法將返回該結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM