Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 死锁:插入与从多个表中选择。快照隔离?_Sql_Sql Server_Deadlock - Fatal编程技术网

Sql 死锁:插入与从多个表中选择。快照隔离?

Sql 死锁:插入与从多个表中选择。快照隔离?,sql,sql-server,deadlock,Sql,Sql Server,Deadlock,在我的数据库中有两个密切相关的表。 有一个经常被称为SP的程序,它将一些行插入到事务中的两个表中,并将其他几个位置从这些表中进行选择 在两个表上插入take X锁,在它们上选择take S或IS锁。由于共享锁的获取顺序因查询而异,因此一些共享锁偶尔会因INSERT事务而死锁 有没有什么好方法可以避免这些死锁(NOLOCK可能不符合“好”的条件) 到目前为止,我能想到的唯一通用解决方案是使用快照隔离级别。然而,它会增加一些性能开销,我还没有找到任何关于这个开销有多大的可靠数据。您是否在事务中从这些

在我的数据库中有两个密切相关的表。 有一个经常被称为SP的程序,它将一些行插入到事务中的两个表中,并将其他几个位置从这些表中进行选择

在两个表上插入take X锁,在它们上选择take S或IS锁。由于共享锁的获取顺序因查询而异,因此一些共享锁偶尔会因INSERT事务而死锁

有没有什么好方法可以避免这些死锁(NOLOCK可能不符合“好”的条件)


到目前为止,我能想到的唯一通用解决方案是使用快照隔离级别。然而,它会增加一些性能开销,我还没有找到任何关于这个开销有多大的可靠数据。

您是否在事务中从这些表中选择或更新任何内容?如果没有,您可以尝试对插入和其他选择使用行锁提示(行锁通常不会升级为页锁或表锁,除非选择结果中的行太多)。如果是,则您可以尝试updlock提示选择SP内部事务。

SP是否在事务内部从这些表中选择或更新任何内容?如果没有,您可以尝试对插入和其他选择使用行锁提示(行锁通常不会升级为页锁或表锁,除非选择结果中的行太多)。如果是,则您可以尝试updlock提示选择SP内部事务。

我在系统中使用快照。这肯定不是免费的,但替代方案也不是免费的——阻塞也会消耗资源。使用rowlock并不总是有帮助。 快照还为您提供数据的一致时间点快照;否则,您将面临一些微妙的错误


还有一件事:即使只有一个表,也可能出现死锁,例如:

我在系统中使用快照。这肯定不是免费的,但替代方案也不是免费的——阻塞也会消耗资源。使用rowlock并不总是有帮助。 快照还为您提供数据的一致时间点快照;否则,您将面临一些微妙的错误


还有一件事:即使只有一个表,也可能出现死锁,这里的示例是:

不幸的是,行级锁定也会出现问题。其中一个表上有一个索引,INSERT事务对其值采用X键锁,SELECT语句对其尝试S锁。基本上,争用只会移动到该索引。该索引位于bool列上,因此键锁基本上锁定了表的整个“有趣”部分。因此,在某种意义上,它与标签锁没有太大区别-(即使以独占方式锁定整个表也不应导致死锁-其他选择只会等到表被释放。在实际insert语句之前,SP事务中是否有select语句?没有。有两个表,因此出现了死锁。不幸的是,问题也表现为行级锁定。o上有一个索引在其中一个表中,INSERT事务对其值使用X键锁,SELECT语句对其尝试S锁。基本上,争用只会移动到该索引。索引位于bool列上,因此键锁基本上锁定表的整个“有趣”部分。因此,在某种意义上,它与TAB锁没有太大区别-(即使以独占方式锁定整个表也不会导致死锁-其他选择只会等到表被释放。在实际insert语句之前,SP事务中是否有select语句?没有。有两个表,因此会出现死锁。您的选择是否正在扫描表?其中一些可能正在扫描(有不同的选择)。它们中的大多数应该使用索引,因此很可能只进行搜索。设置跟踪并使用死锁图,查看导致死锁的实际SQL。其他任何操作都只是猜测锁定和扫描。您的选择是否正在执行表扫描?其中一些可能正在执行扫描(有不同的选择)。它们中的大多数应该使用索引,因此很可能只查找。设置跟踪并使用死锁图,查看导致死锁的实际SQL。其他任何操作都只是对锁定和扫描的猜测。