目前我想知道,为什么有些时候ADO.NET
直接抛出一个表锁异常,当一个表被锁定并且某些时候执行的语句等待,直到表不再被锁定为止。表锁何时导致异常,何时不导致异常?可悲的是,我没有代码可以重现两种情况。
Sybase SQL
中是否有任何规则可以指定此行为?
谢谢大家!
答案 0 :(得分:1)
Sybase和MsSql共享相同的历史代码库。回到过去(pre sql 2000)和Sybase同一时代。供应商都没有解决他们的锁定问题。他们每个人都可能处于死锁状态。问题在于他们使用的逻辑。想象一下死锁的情况,比如在4路停车时开车。想象一下,当两条记录(汽车)同时进入时,规则是否说右边屈服。这种方法很好,除非在4辆汽车同时到达的情况下,每辆汽车都试图屈服于右侧的汽车。你遇到了僵局。在当天,DBA必须选择一条记录来终止该事务(阻止其完成)以允许清除死锁。后来MsSql实现了逻辑,它自动选择要杀死的记录。他们还改进了锁定逻辑,因此对于未来的版本,死锁的频率要低得多。因此,有时它可以工作,有时它不起作用是由你的记录驱动被选择终止的那个或其他死锁完成允许你的记录被处理。
Oracle更好地锁定逻辑。它们保留给定字段的多个副本,具体取决于多个进程是否同时修改它。当您执行select时,您将获取已提交的记录,并且不会运行Sybase / MsSql锁定方案等待完成的不完整进程。后来MsSql版本比Sql 7和sql 2000做得更好,这是一个更大的问题。 Sybase可能已经经历了相同的改进。
有一些方法可以通过将大表分解为较小的表并批量更新从较小的表到较大的表来减少此锁定问题。把它想象成左右桌子。当您将高容量插入活动左表时,右表将插入主表中。然后切换并在左表移动到主表时对右表执行高容量插入。这会破坏表之间的事务,并减少多个进程同时命中同一个表的机会(减少死锁)。但这意味着您没有最新数据,因为左右表中的记录未完全处理。