2014-12-05 130 views
0

我最近得到了一个ASP类网站。并有一个奇怪的问题。asp插入数据库重复数据

语言:ASP。

数据库:Oracle,

当我插入数据库。如果有重复的数据(这里忽略了Oracle主键setting.it是一个老的系统,我们最好不要更改数据库。) 那么我们的验证之前插入DB:

sql="select 1 from tablename where condition...." 
result=runsql(sql) 
if not result.eof then 
'here means DB has data already then we return false. and exit the function. 
exit function 
end if 

'Insert Into DB statement 

我用批处理文件上传。意味着文件有很多记录。例如50个记录。 然后我们用两台电脑打开本网站并点击提交按钮同时上传文件。

我们发现数据库有一些重复的data.only部分,不是全部。

我不知道发生了什么事。我们在插入数据库之前已经添加了验证。

有人可以帮助我吗?

这个网站没有线程的东西。

+0

查找“比赛条件”。祝你好运。 – 2014-12-05 03:39:19

+0

那么有什么解决办法? – 2014-12-05 08:17:10

回答

0

问题是您的代码中存在争用条件。从逻辑上看来,你的代码如下所示:

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 

祝您好运。

+0

感谢您的耐心和细节回复。对不起,有关锁的一个问题,不同的PC上传不同的文件。只有该文件具有重复的数据。如果锁定文件,意味着这个文件不能共享读取。但我们上传不同的文件。这样可以吗? – 2014-12-08 06:29:09