2

我有以下情况:存储过程间歇性地使用两个表。我必须同时执行这个 sp(比如同时执行 50 个)。这让我在大约 33% 的情况下陷入僵局。问题是:在这里使用 sp_getapplock 合适吗?我要做的就是添加:

exec sp_getapplock @Resource = 'resource_name', @LockMode = 'exclusive',@LockTimeout = '60000', @DbPrincipal = 'dbo'

作为事务中的第一个命令,一切似乎都在工作。除了并发,但没关系。令人不安的是,我正在尝试做数据库实际应该做的事情。也许这种方法有更好的选择或严重的缺点?

4

1 回答 1

5

您现在可能已经解决了这个问题,但以防万一。负载下的大型复杂数据库几乎肯定会不时遇到死锁。数据库很难预测到能够确定在流程后期是否存在资源争用所需的程度。您可以做很多事情来最大程度地减少死锁,包括良好的索引、结构良好的表访问等等(那里有大量信息)。但是,有时您可能无法以避免死锁的方式构建代码,并利用sp_getapplock绝对不是坏事。正如您所指出的,它确实会导致瓶颈,因为您不再具有并发性。但是消除死锁的好处可能不仅仅是在性能方面弥补了它。对我来说不幸的是,我在我的一个 SP 中尝试了类似的东西,但调用sp_getapplock本身会导致死锁 - 所以它并不总是能保证解决问题。

从根本上说,它确实归结为您想要实现的目标。但请确保您使用的数据库越复杂,您需要手动调整它的各个方面的机会就越大——它不会为您完成所有工作,这就是为什么仍然需要优秀的数据库专家的原因。我想说的是,除非您对 SP 是单线程有特定要求,否则使用sp_getapplock不应该是您解决问题的第一次尝试——我只使用了 3 次或其他什么。但是,鉴于您的情况,我肯定会选择它,因为它可以解决您的问题,不需要您了解 SP 的复杂内部结构,并且可能没有任何不良副作用。最有可能的是它可能会变慢 - 但听起来你没有注意到这一点?

于 2013-02-25T21:50:42.040 回答