Performance “重新定义数据库”;“交易性”;spring批处理作业上的边界

Performance “重新定义数据库”;“交易性”;spring批处理作业上的边界,performance,transactions,spring-batch,Performance,Transactions,Spring Batch,有没有办法在spring批处理作业上重新定义数据库“事务”边界 背景: 我们有一个简单的付款处理作业,它读取x个付款记录,处理并将数据库中的记录标记为已处理。目前,编写器执行RESTAPI调用(到支付网关),处理API响应并将记录标记为已处理。我们正在采用面向块的方法,这样在整个块完成之前更新不会刷新到数据库中。由于基本上整个读/写都在一个事务中,我们开始看到过多的数据库锁和争用。例如,如果API需要很长时间才能响应(比如30秒),那么整个应用程序就会开始受到影响 显然,我们可以将API调用的超

有没有办法在spring批处理作业上重新定义数据库“事务”边界

背景:

我们有一个简单的付款处理作业,它读取x个付款记录,处理并将数据库中的记录标记为已处理。目前,编写器执行RESTAPI调用(到支付网关),处理API响应并将记录标记为已处理。我们正在采用面向块的方法,这样在整个块完成之前更新不会刷新到数据库中。由于基本上整个读/写都在一个事务中,我们开始看到过多的数据库锁和争用。例如,如果API需要很长时间才能响应(比如30秒),那么整个应用程序就会开始受到影响

显然,我们可以将API调用的超时时间缩短为较小的值。。但这仍然不能解决表可能被锁定的时间超过预期的问题。理想情况下,我们希望数据库事务尽可能短。我们的想法是,如果工作的“肉”可以在数据库事务之外完成,我们就可以绕过这个问题。因此,如果API调用发生在数据库事务之外。。我们可以再花几秒钟来接受响应,而不是导致/增加长锁定持续时间

这是正确的方法吗?如果不是的话,建议用什么方法来处理这个“简单”的工作?是否有其他批处理工具更适合此任务?(如果弹簧批次不是正确的选择)


如果需要,可以提供更多的上下文。

对于您的所有问题,我没有一个准确的答案,但我会尝试给出一些指导

由于基本上整个读/写都在一个事务中,我们开始看到过多的数据库锁和争用。例如,如果API需要很长时间才能响应(比如30秒),那么整个应用程序就会开始受到影响

从一开始,术语“批处理”或“批处理”中的处理数据就是基于将一批记录视为一个单元的想法:要么处理所有记录(无论术语“过程”的含义如何),要么不处理任何记录。这种“全有或全无”语义正是SpringBatch在其面向块的处理模型中实现的。实现如此(强大)的资产需要权衡。在您的情况下,您需要在一致性和响应性之间进行权衡

显然,我们可以将API调用的超时时间缩短为较小的值。。但这仍然不能解决表可能被锁定的时间超过预期的问题

区块大小是对事务行为影响最大的参数。您可以做的是尝试减少单个事务中要处理的记录数,并查看结果。没有最佳价值,这是一个经验过程。这还取决于处理块期间调用的API的响应能力

我们的想法是,如果工作的“肉”可以在数据库事务之外完成,我们就可以绕过这个问题。因此,如果API调用发生在数据库事务之外。。我们可以再花几秒钟来接受响应,而不是导致/增加长锁定持续时间


避免在实时系统上执行此类更新的一种常见技术是将处理转移到另一个数据存储,然后在单个事务中复制更新。其思想是使用给定的批id标记记录,并将这些记录复制到不同的数据存储(甚至是同一数据存储中的临时表),批处理过程可以使用这些记录,而不会影响实时数据存储。处理完成后(可以并行进行以提高性能),记录可以在单个事务中标记为在实时系统中处理(这通常非常快,可以基于批次id来确定要更新的记录)。

感谢您的回复。最终,我认为这取决于特定作业的功能,但这意味着几乎所有读取和写入生产数据存储的spring批处理作业最好保留自己的暂存表,以便spring批处理使用?对于这个特定的作业,我们将读取页大小设置为100,而卡盘大小设置为10。这种类型的读取页面大小值是否与推荐的块大小配置不同?不一定,只要事务边界清晰,就可以共享表。关于页面大小和区块大小,最好将它们设置为相同的值,请参见此处的javadoc:
设置相当大的页面大小,并使用与页面大小匹配的提交间隔,应该可以提供更好的性能。