【问题标题】:Avoiding duplicates避免重复
【发布时间】:2017-09-26 21:06:16
【问题描述】:

假设我们有一个文件,以及一些处理它并发送数据的作业:

  1. 进入数据库
  2. 到外部服务

我们能否保证只处理文件一次或至少确定出现问题并通知用户以便他手动解决此问题?

【问题讨论】:

  • 谁把文件放在那里?我的意思是某人?还是其他一些流程呢?
  • @UsmanRana,是的,这是一个不同的过程
  • 您创建的数据行是否有任何类型的唯一标识符?文件呢?您是否需要担心重新处理之前部分完成的文件?
  • @TracyMoody,没有唯一标识符。数据必须经过全面处理,不得重复。

标签: database database-design architecture duplicates


【解决方案1】:

是的,你可以。

您可以在数据库中创建一个表来存储文件的名称和标志/状态(如果已读取,则为是,否则为否)。当进程在该位置提供文件时,请确保同一进程更新数据库中该文件的名称(如果名称每次都不同)和标志/状态。您的文件读取过程可以从数据库中获取文件的名称并将该文件转储到您的任何位置以及完成后,它应该将标志更新为read 或其他任何内容。这样可以避免多次读取文件。

【讨论】:

    【解决方案2】:

    我会在您的数据库中存储两个信息表。

    1. 已处理的文件行,就像您已经在做的那样。
    2. 文件本身的记录。包括:
      • 文件名
      • 处理是否成功、失败、部分成功
      • SHA1 散列校验和,可用于稍后检查文件的唯一性

    当你去处理一个文件时,你首先检查校验和是否已经存在。如果是这样,您可以停止处理并记录问题。或者您可以将该信息放在文件表中。

    还要确保在已处理的行和文件之间存在外键关联。这样,如果确实出现问题,进行人工干预的人可以追踪受影响的线路。

    【讨论】:

      【解决方案3】:

      Usmana 或 Tracy 的答案实际上都不能保证文件不会被多次处理,并且您的工作不会向数据库和外部服务发送重复的请求(您的问题中的 #1 和 #2)。两种解决方案都建议保留日志并在所有处理完成后对其进行更新,但如果在您尝试在最后更新日志时发生错误,您的作业将在下次运行时再次尝试处理该文件并将重复请求发送到数据库和外部服务。使用 Usmana 和 Tracy 建议的解决方案来处理它的唯一方法是在事务中运行所有内容,但在像您这样的分布式环境中这是一项相当具有挑战性的任务。

      解决问题的一个常见方法是优雅地处理对数据库和外部服务的重复请求。实际实现可能会有所不同,但例如,您可以向数据库添加唯一约束,并且当作业尝试插入重复记录时,将引发异常,您可以在作业中忽略该异常,因为这意味着所需的数据已经在分贝。

      我的回答并不意味着您不需要 Usmana 和 Tracy 建议的日志表。您确实需要它来跟踪处理状态,但它并不能真正保证不会对您的数据库和外部服务产生重复的请求,除非您使用分布式事务。

      希望对你有帮助!

      【讨论】:

        猜你喜欢
        • 2021-08-01
        • 2011-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-09
        • 2014-03-07
        • 2020-08-21
        • 1970-01-01
        相关资源
        最近更新 更多