我有一个在ASP.NET中设计的Web门户,我们要求客户输入数据。在单击提交按钮时,我所做的只是读取数据并调用存储过程将其插入表中。在同时从多台计算机插入数据时,SQL Server 2005中似乎存在问题。我们在实验室中测试了三台计算机,结果是我们只在一台机器上成功插入了数据,而在另外两台机器上我们得到了错误。
我在存储过程中使用了事务,并尝试将隔离级别设置为READ_UNCOMMITTED,SERIALIZABLE和SNAPSHOT。似乎没有什么工作正常。过去一天对此感到沮丧。任何帮助高度赞赏。
谢谢, 的Manoj
答案 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)
标记为回答的回复讲述了死锁。虽然,没有提供足够的信息来假设这一点,所以它可能只是阻止等待问题。
您看到了哪个错误:
由于主题启动器写道:“但是表只是锁定并在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分钟。