由于长时间运行事务导致SQL Server 2000中的数据不一致

时间:2011-04-06 06:32:54

标签: sql sql-server-2000

我们正面临着一个生产服务器的情况。 我们有一个特定的Store过程,它在DB中最大的一个表上执行Insert操作(它有超过几百万行)。此表是数据库中最繁忙的表,并且有许多依赖于它的操作。

最近我们在一个特定的生产服务器上遇到了一个问题。

我们在一次交易中执行插入SP以及其他一些更新SP,并且我们经常面临插入SP的“长时间运行事务”问题。当我们遇到此问题时,我们会在数据中找到插入表中的典型行为。日期时间列值将作为“null”插入。对于所有行,它会发生一些时间,对于几行,它会发生一些时间。日期时间值从应用程序传递。 但是插入操作之前和之后执行的其他更新操作运行良好。

我们在测试环境中运行了sql profiler跟踪(不在生产​​服务器中),但发现每次都正确传递datetime值。

当我们在生产中遇到问题时,我们会注意到:

  1. @@ trancount等于'0'但是 DBCC OPENTRAN显示 特别是公开交易。
  2. “上次等待”类型的值为“NETWORKIO”。
  3. Waittype为'0x0000'。
  4. 状态为“正在睡觉”。
  5. ISOLATION LEVEL是READ UNCOMMITTED。
  6. 所以我们关注的是

    1. 为什么日期时间仅在此特定情况下插入为“空”?
    2. 如何避免这种情况以及长期交易?
    3. 在某个特定服务器中可能出现这种情况的原因是什么?
    4. 提前感谢您的帮助,

      作者Abhijit

3 个答案:

答案 0 :(得分:1)

我认为有些事情需要在这里同时解决。首先,也是最重要的,我强烈建议您查看该事务,看看您可以做些什么来减少它对系统的负担。它可以分解为多个较小的交易吗?添加更好的索引会有帮助吗?捕获数据的子集并将其放入临时表会减少针对主表运行的SELECTS的数量吗?这里的问题清单可能会持续一段时间。

接下来,查看正在启动事务的“应用程序”。它正在传递日期?如果是这样,它是如何做到的?如果它只是传入GetDate()那么它就让SQL Server完成工作。但是,如果应用程序传入日期值,我将确保此日期值始终有效。如果是,请查看表格以确保正确设置日期格式。例如,如果您的应用程序以14-05-2011的欧洲日期格式传递,那么您的应用程序可能会窒息,因为它预期的月 - 日 - 年,因为14不会转换为一个月。

第三,查看表格,看看你是否设置了任何触发器。如果这样做,请仔细查看每个触发器。触发器很可能在您的事务中导致冲突。也许您正在编写数据并且您的触发器将返回并更新数据(或者它正在评估日期并说它无效 - 请参阅上面的示例)。

第四,在数据离开交易之前检查数据。在进入时读取它并在执行INSERT后读取它。也许在事务完成后会有一个客户端操作正在消除日期值。

最后,您需要查看您的测试环境。如果这在测试中有效,但它不在生产中,那么两个系统之间就会有所不同。无论是直接还是间接,这都是原因。也许它与硬件有关(坏RAM?)或者它可能在设置中有所不同(锁定,客户端试图对数据执行操作的事实等)。

除此之外,这里还有一个论坛链接,其中包含一些其他可能的答案:

http://groups.google.com/group/comp.databases.ms-sqlserver/browse_thread/thread/1063b65df1f97492/8649bee2002646a2

答案 1 :(得分:1)

听起来你的代码很乱。建议将插入和更新等隔离到较小的事务中。

要测试您的挂机发生的位置,您可以尝试的一件事就是以打印的形式将一些里程碑添加到您的程序中('Made it this far ...')。然后从SSMS执行该过程并检查消息窗口。这是一种难看的调试方式,但如果您不想使用较小的事务或陷阱@@ error等,它可能是您的最佳选择。

答案 2 :(得分:1)

“我们在一次交易中执行插入SP以及其他一些更新SP”

我建议将插入和更新分离。如果您知道需要在插入后进行一些更新,那么更新的触发器可能是正确的答案。

我还建议您分析锁定/阻止。我这样说是因为根据你所说的,你很可能在你的根事务中不止一次地追踪相同的行,这可能是因为将所有这些活动捆绑在同一个proc中的可能原因。