我有以下情况:存储过程间歇性地使用两个表。我必须同时执行此sp(同时50)。这让我在大约33%的案件中陷入僵局。 问题是:在这里使用sp_getapplock是否合适?我所做的就是添加:
exec sp_getapplock @Resource = 'resource_name', @LockMode = 'exclusive',@LockTimeout = '60000', @DbPrincipal = 'dbo'
作为事务中的第一个命令,一切似乎都在起作用。除了并发,但没关系。令人不安的是,我正在尝试做数据库实际应该做的事情。也许这种方法有更好的替代方案或严重的缺点?
答案 0 :(得分:6)
你现在可能已经解决了这个问题,但万一它会有所帮助。负载下的大型复杂数据库几乎肯定会遇到死锁。数据库很难向前看,以便能够确定在此过程的后期是否存在争用资源的程度。你可以做很多事情来减少死锁,包括良好的索引,结构良好的表访问等等(有很多信息)。但是,合理的情况是,您无法以避免死锁的方式构造代码,并且使用sp_getapplock绝对不是一件坏事。正如您所知,它确实会导致瓶颈,因为您不再具有并发性。但消除死锁的好处可能远远超过它的性能。对我来说不幸的是,我在我的一个SP中尝试了类似的东西,但是对sp_getapplock的调用本身就会导致死锁 - 所以它并不总能保证解决问题。
从根本上说,它确实归结为你想要实现的目标。但是要确保你使用的数据库越复杂,你就越需要手动调整它的各个方面 - 它不会为你完成所有这些,这也就是为什么仍然需要优秀的数据库大师。我会说,除非你有一个特定的要求SP是单线程的,使用sp_getapplock不应该是你第一次尝试解决问题 - 我只使用了3次或者其他东西。但是考虑到你的情况,我肯定会使用它,因为它解决了你的问题,不要求你理解SP的复杂内部结构,并且可能没有任何不良副作用。最有可能的是它可能会减速 - 但听起来并不像你注意到的那样?