繁体   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