asp插入数据库重复数据

时间:2014-12-05 03:07:05

标签: oracle asp-classic

我最近有一个ASP级网站。并且遇到了一个奇怪的问题。

语言:ASP。

数据库:Oracle,

当我插入数据库时​​。如果有重复数据(这里忽略oracle主键设置。这是一个旧系统,我们最好不要更改数据库。) 然后我们在插入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条记录。 然后我们用两台电脑打开这个网站,然后点击提交按钮同时上传文件。

我们发现数据库有一些重复数据。只是其中的一部分,而不是全部。

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

有人可以帮助我吗?

这个网站没有线索。

1 个答案:

答案 0 :(得分: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

祝你好运。