通过有意设计的+高度并发的交易最大限度地减少死锁?

时间:2011-03-25 20:54:47

标签: sql sql-server sql-server-2008

我目前正致力于在SQL Server 2008中对不同的隔离级别进行基准测试 - 但是现在我已经陷入了似乎是一个微不足道的死锁问题,但我似乎无法弄明白。希望这里有人可以提供建议(我是SQL的新手)

我目前有两种类型的事务(用于演示脏读,但这无关紧要):

交易类型A:选择表A中的所有行。

事务类型B:在表A的所有行中设置值'cost'= 0,然后立即回滚。

我目前运行1000个线程和10,000个事务的线程池,其中每个线程在执行事务类型A和事务类型B之间随机选择。但是,即使强制行锁定,我也会遇到大量死锁。

我认为死锁正在发生,因为获取了锁的行排序 - 也就是说,如果类型A和类型B'扫描'表A的顺序相同,例如从上到下,这种死锁不会发生。但是,我无法弄清楚如何让SQL Server在SELECT和UPDATE语句中维护行排序。

任何提示?第一次到stackoverflow的海报,所以请温柔: - )

编辑:故意将隔离级别设置为READ_COMMITTED以显示它消除了脏读(并且确实如此)。死锁仅发生在等于或高于READ_COMMITTED的任何级别;显然,READ_UNCOMMITTED上没有发生死锁。

编辑2:这些事务正在SQL Server 2008R2上的一个新的AdventureWorks LT实例上运行。

1 个答案:

答案 0 :(得分:1)

如果要启动事务以更新所有行,键入B,然后回滚事务,则需要为所有行上的整个事务保留锁定。即使您有行级锁,也需要为整个事务保留锁。

如果你有页面级别或表级别锁定,你可能会看到更少的死锁,因为这些更容易为Sql Server处理,但是你仍然需要在交易正在进行时保持这些锁定。

在设计高度并发的系统时,应避免锁定整个表的查询。我建议使用以下MicroSoft指南来理解锁定并降低其影响:

http://technet.microsoft.com/en-us/library/cc966413.aspx