问题是您的代码中存在争用条件。从逻辑上看来,你的代码如下所示:
Open file
Repeat
Read record from file
Check if record exists in table
If no record in table
Add record to table
End repeat
Close file
的竞争条件是,如果你必须在执行两道工序,每一个可以检查,看看是否在表中存在一个特定的记录;两者都会返回一个表示记录不存在的返回值;然后双方将继续插入记录。显然,数据库中没有主键或唯一键约束来防止重复数据,因此每个进程插入的数据都被添加到表中。
您遇到的情况发生是因为两个进程不知道对方正在做什么。每个进程都是独立调度的,并且不仅在它们之间共享处理器,而且与所有其他进程同时运行,并且它们的执行被不可预知地中断以允许其他进程运行。现在,让我们考虑以下情况:
Process 1 starts
Process 2 starts
Process 1 issues an I/O request to read a record from the
file, relinquishing the CPU
Process 2 issues an I/O request to read a record from the
file, relinquishing the CPU
I/O for process 1 completes and process 1 is rescheduled for execution
I/O for process 2 completes and process 2 is rescheduled for execution
Process 2 executes, issues an SQL request to see if the record exists in the
table, and relinquishes the CPU
Process 1 executes, issues the same SQL request, and relinquish the CPU
SQL request for process 2 completes; process 2 is rescheduled for execution
SQL request for process 1 completes; process 1 is rescheduled for execution
Process 1 executes and finds the record does not exist in the file
Process 1 adds the record to the file
Process 2 executes and finds the record does not exist in the file
Process 2 adds the record to the file
请注意,进程的执行顺序已经交换了几次。这是正常的 - 你无法控制哪个进程将被安排执行,你也不需要关心它。
您的每个进程都已正确找到来自该文件的记录在查看数据库时不存在并因此添加它。不幸的是,你的每一个进程都不知道另一个进程或多或少地在同一时间执行完全相同的事情。
IMO最容易做的事情是让每个进程都试图锁定文件,以便只读取文件。这会阻止其他进程读取和处理文件中的数据,从而防止出现这种问题。它看起来像你使用VB.Net,所以你应该能够使用FileSystem.Lock来锁定文件。您的程序的逻辑流程将改为如下所示:
Open file
Lock the file
- either wait until the file can be locked successfully or terminate because the
file is in use by another process
Repeat
Read record from file
Check if record exists in table
If no record in table
Add record to table
End repeat
Unlock the file
Close file
祝您好运。
查找“比赛条件”。祝你好运。 – 2014-12-05 03:39:19
那么有什么解决办法? – 2014-12-05 08:17:10