SQL Server - 确保只有一个事务尝试创建表

时间:2011-12-07 10:24:58

标签: sql-server sql-server-2005 sql-server-2008

内部应用程序需要根据一些提供的标准动态创建SQL表。这个应用程序有多个消费者。

IF (NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND  TABLE_NAME = 'SomeTableName')) 
BEGIN
   -- Create table in here.
END

要做到这一点,我在sproc中有上面的基本结构。我知道可能的竞争条件,所以我的第一个解决方案是向SELECT语句添加一些锁定提示,以确保在其他事务完成之前阻止检查表存在的所有其他事务。但是,无论我使用哪种提示,这都行不通。

我的下一个解决方案是将表创建包装在TRY..CATCH中,这样即使它确实失败了,我也可以忽略错误。但是,CREATE TABLE语句的失败会导致事务失败,所以即使我忽略了错误,也无法继续。

我的最后一个解决方案是使用TRY..CATCH构造,如果出现错误,那么GOTO创建一个新事务的sproc顶部,一切都很顺利,因为表存在于第二轮

我对解决方案不满意,因为它看起来像是黑客攻击。谁知道这个问题的干净解决方案的任何SQL大师?

为了澄清一点,我上面讨论的解决方案对性能影响不大,所以我真的在寻找一个没有大的性能影响的干净解决方案。

1 个答案:

答案 0 :(得分:2)

使用信号量(又名手动锁定)和sp_getapplock(代码顶部)和sp_releaseapplock(代码底部)来确保只有一个进程。

第二个进程将根据您的sp_getapplock参数失败或等待或超时