聚合与乐观锁定

时间:2015-09-27 09:20:38

标签: java synchronization

我们正在开发一个位于两个文档处理系统之间的适配器组件。

简要文档生命周期描述

  1. 系统A逐个向适配器发送文档。
  2. 适配器收集这些文档,预先验证并将文档转换为系统可理解的格式。转换后的文档存储在数据库中。
  3. 每隔5分钟,转换后的文档将从数据库中获取,打包到包中并发送到系统B.
  4. 文档处理详细信息

    对于文档,可能会对适配器进行更新。此更新看起来像一个普通文档,其标识符与原始文档相同,但有几个字段不同。当这样的更新到来时,有以下要求:

    1. 如果将原始文档发送到系统B,请跳过更新;
    2. 如果原始文档未发送到系统B,则仅发送更新。
    3. 如上所述,文档处理分为两个阶段:逐个验证转换 - 持久化文档和文档聚合发送。

      每个文档都有一个专用的数据库记录。更新到来时,会更新相应的记录(不会创建单独的记录)。当文档到达时,它具有“新”状态,在经过验证和转换后,它将获得“准备发送”状态。作为包裹的一部分发送后 - “已发送”状态。

      问题陈述

      有可能出现以下情况:

      1. 文档到达适配器 - 获取“新”状态;
      2. 文档经过验证并成功转换 - “准备发送”
      3. 包含所述文档的文档集合从数据库中获取,并且包转换过程已开始 - 所有文档仍处于“准备发送”状态;
      4. 更新到达包中的一个文档,并且相应的事务提交 - 此文档记录处于“准备发送”状态,但是几个字段已更改(Hibernate- @ Version-marked列也是如此)
      5. 形成一个包,在发送阶段,适配器尝试为包中的所有文档设置“已发送”状态,但失败并显示OptimisticLock异常,这意味着必须重新处理整个包。
      6. 我们的适配器的速率为每秒250条消息,通常一个软件包平均包含20000个转换文档,并且面临所述问题的可能性相当高。禁止形成和发送几个较小尺寸的包裹,也禁止丢失文件或发送重复的文件。

        乐观锁定在适配器中至关重要,因为它可以在多个并行线程中抓取和处理文档,因此可以并行处理原始文档和更新...

        解决方案提示

        我们正在考虑在形成包之前引入一个新的状态,例如'On Package Forming',并在单独的事务中为每个文档设置此状态:如果某些文档会引发OptimisticLock异常,我们将只重新处理文献。这个解决方案看起来很慢。

        请您为此案例提出解决方案吗?也许我们必须彻底改变这种方法?

0 个答案:

没有答案