我对Spring有经验,但对Spring Batch还是陌生的。现在,我的任务是将数据结构从一个数据库中的简单结构迁移到另一个数据库中的复杂结构。数据结构对应于一个我将这样命名的对象层次结构
OldParent 1 --> n OldChild // old system
NewParent 1 --> n NewChild // new system
在旧的db中,只有两个表,而在新系统中,事情变得更加复杂,并且有8个表,但这暂时不相关。
基本上,我想使用一个简单的基于JDBC的解决方案,将行映射器从OldParent中读取并转换为NewParent。
因此,这是一个基本的配置代码段:
<batch:job id="migration">
<batch:step id="convertLegacyData">
<batch:tasklet>
<batch:chunk
reader="parentReader"
writer="parentWriter"
commit-interval="200" />
</batch:tasklet>
</batch:step>
</batch:job>
在这种情况下,parentReader将获取并转换OldChild对象,可能委托给childReader / childWriter对象。
问题是这样的:尽管有数十万个父级,但每个父级可以有零个到几百万个子代,因此基于父级的提交间隔根本没有帮助,但是我非常希望有一个可配置的提交间隔。
因此,另一个解决方案是使工作流基于子级:
<batch:job id="migration">
<batch:step id="convertLegacyData">
<batch:tasklet>
<batch:chunk
reader="childReader"
writer="childWriter"
commit-interval="200" />
</batch:tasklet>
</batch:step>
</batch:job>
在这种情况下,childReader还必须读取OldParent对象并编写NewParents,委托给parentReader和parentWriter对象。这里的主要缺点是我将丢失所有没有关联的OldChild对象的OldParent。
第三种可能的情况是
OldParent -> NewParent
和OldChild -> NewChild
具有两个不同的工作流程。 (我必须维护一个映射表,该表存储OldParent和NewParent id之间的关系,但是我可以使用包括commit-interval在内的标准配置。还有其他可能性吗?您会推荐以下哪一项作为最佳做法?
最佳答案
它没有N记录提交间隔配置吗?它不是使用类似于BatchUpdates(JDBC)之类的东西,因此您可以配置N个大小的批处理更新和每个批处理更新的提交。
如果没有,我有一个hack :)
制作自己的java.sql.Connection实现。一个将所有命令传递给原始连接的命令,并在每次第N次更新后执行一次提交... :)
如果您使用的是DatabasePool,则也可以包装原始数据库,以返回与hack的包装连接。
我知道这是一个很奇怪的建议...但是也许这是一次性迁移所需要的。