数据库中的随机记录重复(无意的)

数据库中的随机记录重复(无意的)

我提前为冗长的文字表示歉意;我只是想确保我涵盖了所有事实,以便做出正确的诊断。

我只是对这个问题感到非常困惑,希望有人以前遇到过这个问题或者至少可以对此事提供一些见解。

在过去的几周里,我们的应用程序遇到了一个问题,看似随机的表中的看似随机的记录会自我重复。这似乎没有任何规律或理由,我不认为这是一个编码问题。有时记录重复 3 次,有时重复 20 次以上,以及介于两者之间的所有情况。

我的数据库里几乎每个表上都有一个日期时间字段,我习惯性地添加它们,但我发现记录中很奇怪的一点是,每次发生重复时,真实的记录将具有正确的日期时间戳,例如2010-10-28 16:28:26.903(请注意,毫秒是准确的,并且符合您的预期) - 但重复的记录都具有日期时间戳,如 2010-10-28 16:28:27。000

这就是我说这不是编码问题的原因之一。我原以为,如果存在一些错误的循环,在某个流氓代码块中随机插入一堆记录,则插入的记录的日期时间戳会相隔几毫秒 - 但这里的情况并非如此。所有重复的记录的毫秒数都会减少,并向上或向下舍入到最接近的秒数。

全部其他除 PK/identity 列外,信息完全相同。

据我所知,目前应用程序中大约有 4 个不同的表发生了这种情况,但可能发生在更多表上...我还没有检查(数据库有很多表)。我知道这不会发生在所有表上。它似乎在问题首次发生的表中停止了,现在“蔓延”到其他表。

我复制了一份数据库用于预版本发布阶段/测试,该数据库中也有重复项。该数据库与遇到此问题的实时数据库位于同一台机器上。但是,我们的开发机器上有一个数据库,似乎根本没有这个问题。我想如果这是一个编码问题,我们会在所有三个数据库中看到这个问题。

除此之外,受影响的其中一个表更像是一个后端表。它里面只有两条记录,但其中一条在前几天被重复了 10 次。我们的系统中没有任何代码可以插入记录、更新记录或以任何方式与此特定表交互。没有为其编写的存储过程、没有视图、没有触发器,什么都没有……但其中一条记录却被重复了。我可以看到一个影响其他表的编码问题,但考虑到这个特定的表有重复项,而没有任何代码与之交互 - 我发现这非常奇怪。我还应该提到,这里被重复的记录是几个月前手动插入的。

这些重复也不会在插入真实记录时发生。当它第一次发生时,我做了一些测试 - 认为这是一个编码问题并试图找出代码中的恶意部分。我所有的测试都很好,我无法重现结果。我测试了有问题的区域,检查了数据库,新插入的记录都没有重复。出于好奇,我第二天早上检查了一下,没有插入重复项。那天下午晚些时候我检查了一下,果然,有 24 条重复记录被插入 - 几乎是在事发后 24 小时。

有谁知道数据库进程可能会出现故障并导致这种情况发生吗?插入记录时,内存中会卡住一些东西,一段时间后会多次输出该记录?

我知道这不是你经常遇到的问题,至少我不这么认为。这是我第一次听说这种事。有什么想法吗?即使是瞎猜一下,在这一点上也会很感激。

我知道一个“解决方案”是对受影响的表施加约束以使重复记录不可能出现;但在我去做类似的事情之前,我真的想彻底弄清问题,或者至少对导致问题的原因有某种倾向(如果可能的话)。我想知道我是否可能没有正确设置某些东西,并且可以知道将来如何避免这个问题。如果有问题,我宁愿修复它,而不是掩盖它,让它回来困扰我。墨菲定律,你知道的。

谢谢大家;如果您需要更多信息,我很乐意提供。

编辑抱歉,我应该提到我在生产数据库服务器上使用 SQL Server 2005,在开发机上使用 SQL Server 2008,并且它们都连接到 ASP.net 应用程序

答案1

对表施加约束不是一个“解决方案”(从象征意义上来说)。相反,这是正确的做法。根据定义,数据库模式的设计应使 RDBMS 强制执行约束,以防止在数据库中表示无效数据。

应该作为数据库基本设计的一部分,对表进行约束以防止插入“重复数据”。如果您使用自然主键,则可以“免费”获得此信息。由于您使用的是人工主键(“标识”列),因此您需要对构成自然主键的列进行唯一性约束。

几乎可以肯定,这种情况会发生在您的代码中。多年来,SQL Server 一直受到大量用户的严重攻击。这种类型的 SQL Server 引擎本身的错误早就应该被解决了。

一旦设置了唯一性约束,插入这些重复记录时就会抛出错误,您将能够追溯到它们的来源。如果您的代码中没有相当于“On Error Resume Next”类型的构造,那么当有问题的代码无法对“重复”数据执行插入时,您应该会开始收到错误(未处理的异常等)。

您描述的整个“四舍五入时间”症状让我认为您在代码的某个地方埋藏了一个“实用程序”函数,它通过截断时间来“提供帮助”(因为截断日期时间值相当简单)。

让 SQL Server 抛出约束违规错误,你就能追踪到有问题的代码。即使修复了有问题的代码,也要保留对数据库的约束,因为排除无效数据是数据库工作的一部分。

答案2

我知道这个问题很久以前就发布了,但问题仍然存在。我遇到了同样的问题,我的表中出现了重复的行。我正在使用 Asp.net VB.net 和 SQL Server Express 2016。

由于某种原因,当我使用 GridView.RowUpdating 时记录会重复,即使我同时调试和检查数据库,似乎在我退出 RowUpdating 事件后,记录也会重复。

我使用 ExecuteNonQuery 一次,然后立即关闭连接。我在网上搜索了很多答案,但都不起作用。

但是我发现 GridView.RowUpdating 不喜欢没有 e.Cancel = true,所以我把它放在任何地方,并意识到我可以用它来阻止 RowUpdating 事件运行两次(我一生都找不到原因,也看不到它发生)。所以在我的退出子程序之前我把 e.Cancel = true 放进去,这样就解决了这个问题。

希望我的回答能够帮助有类似问题的人。

相关内容