在SQL Server 2005中同时从同一数据库中的多台计算机插入记录时出现问题

时间:2010-11-12 06:24:53

标签: asp.net sql-server vb.net

我有一个在ASP.NET中设计的Web门户,我们要求客户输入数据。在单击提交按钮时,我所做的只是读取数据并调用存储过程将其插入表中。在同时从多台计算机插入数据时,SQL Server 2005中似乎存在问题。我们在实验室中测试了三台计算机,结果是我们只在一台机器上成功插入了数据,而在另外两台机器上我们得到了错误。

我在存储过程中使用了事务,并尝试将隔离级别设置为READ_UNCOMMITTED,SERIALIZABLE和SNAPSHOT。似乎没有什么工作正常。过去一天对此感到沮丧。任何帮助高度赞赏。

谢谢, 的Manoj

4 个答案:

答案 0 :(得分:1)

我认为这是因为你正在使用交易...

根据 here

  

BEGIN TRANSACTION开始本地化   连接发布的事务   该声明。取决于   当前事务隔离级别   设置,获得的许多资源   支持Transact-SQL语句   由连接发出的锁定   交易直到完成   使用COMMIT TRANSACTION或   ROLLBACK TRANSACTION语句。   交易留下了很长时间   一段时间可以防止其他   用户访问这些锁定   资源,也可以防止日志   截断。

在您的情况下,您使用3pc同时测试了您的应用程序。由于您正在使用事务,如果这些用户在您的数据库(您的SP,表等)中同时使用相同的资源,那么该特定资源将被锁定而其他用户将无法使用它 除非完成或提交第一个用户的交易。

这是我发现的一篇好文章: http://omaralzabir.com/linq_to_sql_solve_transaction_deadlock_and_query_timeout_problem_using_uncommitted_reads/

答案 1 :(得分:1)

标记为回答的回复讲述了死锁。虽然,没有提供足够的信息来假设这一点,所以它可能只是阻止等待问题。

您看到了哪个错误:

  • 1)
    死锁受害者1205错误
    “服务器:消息1205,级别13,状态50,行1 事务(进程ID 5?)在锁资源上与另一个进程发生死锁,并被选为死锁牺牲品。重新运行该交易。“?
  • 2)
    超时错误
    “超时已过期。在完成操作之前经过的超时时间或服务器没有响应。”

由于主题启动器写道:“但是表只是锁定并在5到6分钟后释放”,我相信这是2)的时期,而死锁受害者1)被选中并在5秒内回滚。

另外,有人提到插入来自不同的计算机。由事务COM +组件运行的查询将默认为可序列化的tx iso级别,它排除死锁但增加阻塞争用(等待)。

  

“我在存储过程中使用了事务,并尝试将隔离级别设置为READ_UNCOMMITTED,SERIALIZABLE和SNAPSHOT。似乎没有什么工作正常”

这可能意味着您的设计和索引不是“正确的”,但SQL Server只是使其正常工作。

根据提供的信息,猜测游戏可以提供任何建议。

避免将CL-IX(聚簇索引)放在DML-ed(更新,插入,删除)的列上。 DML到聚簇索引键列将需要CL-IX上的锁(移动行)和所有非聚簇索引(因为非聚集索引的叶级通过CL-IX键值引用行)

您应该有一个索引表,否则整个表将在插入时被锁定(阻塞),从而导致等待时间和超时增加。

阅读"How to resolve blocking problems that are caused by lock escalation in SQL Server"(注意:这是过时的文章。例如,你应该使用TOP而不是那里推荐的ROWCOUNT)

在SQL Server 2005及更高版本中,应考虑READ COMMITTED SNAPSHOT tx iso级别,只要使用默认的READ COMMITTED就可以。

答案 2 :(得分:0)

你可能想考虑死锁。这通常发生在多个用户同时使用存储过程时。为了避免死锁并确保用户的每个查询都会成功,您需要在更新失败期间进行一些处理,为此,您需要尝试catch。这仅适用于Sql Server 2005,2008。

DECLARE @Tries tinyint

SET @Tries = 1

WHILE @Tries <= 3

BEGIN

  BEGIN TRANSACTION

  BEGIN TRY

  -- do your insert statement here

   COMMIT

   BREAK
  END TRY

  BEGIN CATCH

   SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_MESSAGE() as ErrorMessage

   ROLLBACK

   SET @Tries = @Tries + 1

   CONTINUE

 END CATCH

END

答案 3 :(得分:0)

这个过程需要多长时间才能运行?也许你需要的是一些严重的性能调整,如果它导致其他用户试图插入超时。没有一个proc应该锁定表5-6分钟。