当前位置: 首页 > 知识库问答 >
问题:

如何在Spring Batch块中管理较短的事务?

富勇军
2023-03-14

我在使用Spring Batch时遇到问题,似乎找不到解决方案。

所以,我有一个批量处理一些项目在块(大小10)。我还有一个事务管理器,该批处理使用它来在每个块之后保存处理过的项目。

但是我还想实时保存这些项目的一些进展状态。所以在处理一个项目之前,我想保存一个状态,表明这个项目正在进行中。

我似乎找不到实现这一目标的解决方案。我尝试了以下解决方案

  1. 如果我只是用事务性注释来注释我的状态管理器服务,那么状态将在整个区块处理之后提交
  2. 如果我将REQUIRES_NEW作为传播级别添加到注释中,它会起作用。。。但批处理以某种死锁结束(我读到这是REQUIRES_NEW的常见问题)
  3. 所以我最后的猜测是添加第二个事务管理器(在同一个数据源上),并在状态管理器服务上使用它。。。但我得到了与解决方案#1相同的结果(在我看来,这似乎很奇怪,因为我希望这个经理的事务独立于区块事务进行)

有人遇到过这个问题吗?

编辑:这是我的配置,故意简化:

DBC类配置:

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

类作业配置:

@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;
    }
}

类状态:

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

共有1个答案

龚志
2023-03-14

实现这一点的一种方法是使用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。然后执行方法将返回该结果。

 类似资料:
  • 我想用3个步骤建立一个批次。我想配置这个步骤,就像如果有100条记录,当step1读取、处理和写入一个10块时,step02,然后step03开始和结束,然后再次返回step1,读取下一个块。这在Spring批量可能吗?

  • 用例:步骤1:ItemReader:从数据库中读取1000个ItemProcessor块中的数据:处理这些数据。ItemWriter:将数据写入地图,以便下一步使用 步骤2:ItemReader:读取地图ItemProcessor:处理地图数据并获取新对象。ItemWriter:将新的进程对象持久化到数据库中。 现在我希望Map在整个作业中保持不变,目前我已经为Map创建了一个不同的POJO类,并

  • 我正在编写spring批处理,它从平面文件中读取数据,很少进行处理,并将摘要写入输出文件。与reader相比,我的处理器和写入程序相对更快。我正在使用FlatFileItemReader,并尝试了从50-1000开始的各种提交间隔。我的批处理作业必须以更快的速度处理1000万条记录。请告诉我如何提高FlatFileItemReader的速度。粘贴到我的配置文件和映射器类下面,读取字段集并将值设置为

  • 我们的SpringBatch作业只有一个步骤,包括ItemReader、ItemProcessor和ItemWriter。我们用不同的参数同时运行同一个作业。ItemReader是有状态的,因为它包含从中读取的输入流。 因此,我们不希望ItemReader的相同实例用于每个JobInstance(作业参数)调用。 我不太确定哪种是这种情况的最佳“范围界定”。 1) 该步骤是否应该以@JobScop

  • 假设我想使用以下操作码进行短跳: EB CB或JMP rel8 “短跳转,RIP=RIP 8位位移符号扩展到64位” (其中CB是一个字节有符号值,表示EIP寄存器中与方向相关的相对偏移) 也许总是偏移量将偏移量2,因为在这个短跳转中执行时间(参考方向)中的EIP是twobyte指令的基础,但加数总是发生 eb 30=jmp 0x00000032(30) eb e2=jmp 0xffffffe4(