Database design 如何最好地避免多次插入?

Database design 如何最好地避免多次插入?,database-design,windows-services,Database Design,Windows Services,我有一个监控目录更改的服务应用程序 服务应用程序将密切监视目录。下面是它是如何做到这一点的: 睡眠X分钟 浏览目录,看看是否有新的添加 每个添加启动一个线程 重复1-3次 它所做的一件事是将一条记录插入数据库。现在,由于可以同时运行多个线程,所以完全有可能两个线程同时插入记录 我想避免这种同时插入;相反,我希望这些插入可以排队,这意味着在一个时间点只有一个线程可以访问数据库。当已有1个线程访问数据库时,其他服务无法访问数据库 我之所以希望这样做,是因为在电力激增的情况下,我只损失了一笔交易,而不

我有一个监控目录更改的服务应用程序

服务应用程序将密切监视目录。下面是它是如何做到这一点的:

  • 睡眠X分钟
  • 浏览目录,看看是否有新的添加
  • 每个添加启动一个线程
  • 重复1-3次
  • 它所做的一件事是将一条记录插入数据库。现在,由于可以同时运行多个线程,所以完全有可能两个线程同时插入记录

    我想避免这种同时插入;相反,我希望这些插入可以排队,这意味着在一个时间点只有一个线程可以访问数据库。当已有1个线程访问数据库时,其他服务无法访问数据库

    我之所以希望这样做,是因为在电力激增的情况下,我只损失了一笔交易,而不是很多笔交易。

    我正在考虑使用lock语句锁定数据库事务。这是最好的方法吗?


    p/S:我正在编写一个与MySQL数据库对话的.Net服务。

    我将首先了解您为什么要这样做。通常应用程序都是这样运行的,两个客户端同时进行插入是没有问题的(除了代码中的错误方法)

    此外,解决方案也会因场景而异。一种选择是使用microsoft消息队列(MSMQ),并将插入内容移出这些服务,因此插入内容的加载由从队列中读取内容的进程控制

    更新1:我仍然不明白为什么要避免插入并行运行(以及从我在其他回复中看到的内容,我认为其他人会这样做)。我将引述你对这一点的2点评论:

    我之所以要这样做,是因为在电力激增的情况下,我只损失了一笔交易,而不是很多笔

    另一方面:


    这是因为在插入之前,还有其他需要并行处理的冗长作业。只有在插入期间,才需要顺序访问

    如果我单独阅读第一篇,我会认为这是一个让它们并行的理由。你想尽快解决这些问题。按顺序进行实际上会增加插入的时间,因此会有更多的时间发生电涌

    阅读第二篇文章,我认为您可能更关心这些并行运行的进程以及插入没有进入数据库的影响。这同样意味着您希望尽快完成插入,所以这不是按顺序执行插入的理由

    对于内置支持,您可能有一个分布式事务的案例,其中也包括文件系统(ms正在研究文件系统,但我不记得他们是否在较新的操作系统上做过一些事情)。不过,设置分布式事务有点困难(msdtc和对它使用的端口的访问)

    我遵循的一个好方法是向流程中添加更多信息,以便能够告诉流程失败的地方。您甚至可能还没有编写一个自动恢复过程的代码,但至少您知道您将有信息确定是否发生了错误

    最简单的方法是在进程开始时插入,并在进程完成时用标志发出信号。如果这是一个长时间运行的过程,您可能希望有一个更像您不断更新的状态的东西,以便能够告诉它在哪个步骤失败。另一种方法是将状态写入文件系统

    在任何情况下,它只会告诉您成功完成的最后一个步骤,而不会告诉您当前步骤是否能够完成。这使得重试逻辑变得更复杂,因为您不能只在停止的地方继续,您必须检查最后一步是否完成,这取决于每个步骤


    注:如果上述情况属实,则很难从问题中分辨出来。您可能想就长时间运行的进程和/或自动重试提出另一个问题。

    如果您安装了多个windows服务来监视同一文件夹,或者如果您有多线程windows服务,那么您将同时获得多个插入。否则您不必担心。

    一个数据库意味着允许多个进程同时插入数据,所以我看不出您的问题。你有错误吗

    [编辑]你害怕电涌。哪里在服务器上还是在客户端上?以下是您的选择:

  • 服务器崩溃。只要让客户端检查“连接丢失”的错误代码,并让他们重试插入,直到成功。要找出这个错误代码,要么在插入的中间关闭服务器,要么拔出客户端的网络电缆(或者两者都是;有时,对于意外的网络问题,您会得到不同的错误)。

  • 客户机崩溃(更有可能,因为客户机通常是廉价的PC机。如果用户能够访问它,它最终会感染病毒,或者文件系统会损坏,它会耗尽RAM,有人会安装一些“酷”的东西,破坏重要的DLL,或者诸如此类)。在这种情况下,您必须再次启动客户机,检查已经插入的内容(使用应用程序密钥),然后从那里继续


  • 应用程序密钥是与业务流程相关的行的ID。例如,如果您销售卡片,应用程序密钥可以是汽车名称、客户名称以及时间戳。

    为什么每次插入都要创建一个新线程?为什么不简单地在插件上循环呢?只有在需要并行性时才需要线程;在你的情况下,这似乎与你想要的正好相反

    [编辑]


    这是因为在插入之前,还有其他需要并行处理的冗长作业。只有在插入期间,才需要顺序访问。