我想了解Spring Batch是如何进行事务管理的。这不是一个技术问题,而是一个概念性的问题:Spring Batch使用什么方法?这种方法的后果是什么?
让我试着澄清一下这个问题。例如,在TaskletStep中,我看到步骤执行通常如下所示:
这似乎是有道理的。但是2到3之间的失败呢?这意味着业务事务已提交,但Spring Batch无法在其内部元数据中记录这一事实。因此,重新启动将再次重新处理相同的项目,即使它们已经提交。对吗?
我正在寻找对这些细节的解释以及Spring Batch中做出的设计决策的后果。这是否记录在某处?Spring Batch参考指南对此的详细信息很少。它只是从应用程序开发人员的角度解释事情。
Spring Batch中有两种基本类型的步骤,Tasklet步骤和基于块的步骤。每个都有自己的事务详细信息。让我们看看每个:
基于Tasklet的步骤
当开发人员实现他们自己的tasklet时,事务性非常简单。对Tasklet#执行
方法的每次调用都在事务中执行。您是正确的,因为在执行步骤的逻辑之前和之后都有更新。从技术上讲,它们没有包装在事务中,因为我们不想为作业存储库更新支持回滚。
基于块的步骤
当开发人员使用基于块的步骤时,由于增加了跳过/重试的功能,因此会涉及更多的复杂性。但是,从简单的层面来看,每个块都是在事务中处理的。出于前面提到的相同原因,您在基于块的步骤之前和之后仍然有相同的更新,这些更新是非事务性的。
在您的问题中,“如果”场景中,您询问如果业务逻辑完成,但由于某种原因,对作业存储库的更新失败,会发生什么。重新启动时是否会重新处理以前更新的项目。和大多数事情一样,这要看情况而定。如果您使用的是有状态的读写器,比如FlatFileItemReader
,则每次提交业务事务时,作业存储库都会更新为已处理内容的当前状态(在同一事务中)。因此,在这种情况下,重新启动作业将恢复其停止的位置。。。在这种情况下,在结束,并没有额外的记录处理。
如果您没有使用有状态的读写器或已关闭“保存状态”,则需要谨慎一点,最终可能会出现您描述的情况。框架中的默认行为是保存状态,以便保留可重启性。
在会话范围内具有一个简单的CDI bean,其中注入了一个实体管理器: 现在,当通过EL#{myBean.test插入}调用函数时,有两件事似乎很奇怪: 1)将@Transactional注释移动到方法创建(int)我得到: javax.persistence。TransactionRequiredException:JBAS011469:执行此操作需要事务(使用事务或扩展持久性上下文) 2) 改
我在批处理作业中使用多线程步骤来处理来自源数据库的记录并写入目标数据库。该步骤基于块,由JdbcpagingItemReader、Processor和JDBCBathItemWriter组成。我明白,如果在步骤处理期间发生任何异常,数据库事务将回滚整个块。我想了解一下Spring batch在内部是如何管理的?由于这是多线程步骤,因此不能保证处理器和写入器在块的同一线程中执行。块可能由不同的线程处
问题出在@Transactional中,在我的配置中spring应用程序没有使用它。我怎么能修好它? ...REST控制器没有任何事务性方法,它只使用specifiedServices加载实体。依赖集合(如果未加载到服务中)应为空。 应用程序启动程序类: 我还尝试将@Transactional添加到存储库接口中,但对我来说并不起作用 所以我从存储库中删除了@Transactional,创建了其他服
事务处理(transaction processing) 可以用来维护数据的完整性,保证SQL的操作要么完全执行,要么完全不执行,如果发生错误就进行撤销。 保证数据的完整性。 保证数据不受外影响。 事务处理的几道术语 事务(transaction) 一组SQL语句 退回(rollback)撤销执行SQL语句的过程 提交(commit) 将为执行的SQL语句写入数据库表 保留点(savepoint)
在happy path场景中,我有一个spring批处理工作,但现在我将重点放在错误处理上。 但是,在另一个测试中,我想证明一个不可预见的数据库错误会导致作业失败。为此,我创建了一个触发器,该触发器会导致对要插入的表的插入失败。 这似乎起作用了,在writer执行之后,在事务提交期间抛出异常,并且我得到以下日志消息: 这似乎也是预期的行为。问题是,这并不能阻止工作。该步骤退出到SimplyRetr