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