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