寻找有关如何解决此问题的想法。这是交易:
我们有一家公司偶尔向我们发送文件,这些文件位于目录中。在我们这边,我们有一个Windows服务,监视该目录的任何传入文件。一旦服务运行并找到文件,它就会执行代码以开始处理所述文件。该目录一次可以包含1到n个文件。例如,我们可能有1000个文件出现在目录中,Windows服务会看到这些文件并开始将数据放入我们的数据库并发送电子邮件。
该进程以多线程和异步方式运行。它抓取文件,将数据放入数据库,然后向某人发送电子邮件。这里的问题是,当两个进程正在运行并且它们都在使用相同的代码时,有时可以为同一个人生成2封电子邮件。该方法如下:
正在发生的事情是2个线程同时访问此方法并同时读取代码。两者都查看数据库并看到'email flag column'为NO。然后他们发送电子邮件并将列标记为YES。但由于这种情况发生得如此之快,线程(A)在线程(B)读取列之前没有机会标记DB列。
如果两个线程在此方法中背靠背,我已经考虑过将一些代码放入'等待'。就像一个LOCK。但我们做不到。我现在唯一的解决方案是不发送电子邮件。并拥有一天中某些时间运行的控制台应用程序,并向该列中包含0(否)的人发送电子邮件。电子邮件发送后,我们将列标记为1(是)。
这可能不是最好的解决方案,这就是我在这里的原因,让你们中的一些可怕的聪明人帮助我思考一些性感的解决方案。
答案 0 :(得分:1)
你需要锁定。
一种方法是让流程在开始处理之前将电子邮件移动到私人文件夹(针对该流程)。只有一个进程可以移动文件。有你的锁。
修改强>
如果您决定使用数据库在数据库中设置锁定,请注意。
除非您正在使用某些特殊的PInvokes来访问Windows Vista,7或Server 2008上的事务性文件系统,否则您将始终面临将事务扩展到文件系统的问题。
答案 1 :(得分:1)
我会在阅读时更新电子邮件标志 - 使用SP或只是将select和update移动到同一个事务中。例如,如果电子邮件发送失败,那么您始终可以将其返回到0。
答案 2 :(得分:0)
如果您有多个进程和同步问题,则需要某种中央锁定,否则无法解决问题。不知怎的,他们需要沟通。
如果您完全不能按照您的描述进行处理,请尝试使用中央“同步”服务器。 Redis将完成这项工作,它具有原子键操作。在获取文件时获取设置密钥的过程,只要它打开文件并设置一个密钥,说“我已经处理了这个文件而我是进程ID X”。如果其他人对该文件具有锁定,则会取消该进程。在发送邮件之前再次检查,以避免在打开文件和设置锁定之间的时间内出现进一步的争用问题
您可以将键设置为在一段时间后自动过期。