动态表名称的SQL Server同义词和并发安全性

时间:2010-11-12 12:35:52

标签: sql tsql sql-server-2008 concurrency transactions

我正在使用一些商业模式,这些模式有一组类似的表,只有语言名称不同,例如:

Products_en
Products_fr
Products_de

我还有几个存储过程用于访问这些以执行某些管理功能,我选择使用同义词,因为有很多代码,并且将所有内容编写为动态SQL只是痛苦:

declare @lang varchar(50) = 'en'

if object_id('dbo.ProductsTable', 'sn') is not null drop synonym dbo.ProductsTable
exec('create synonym dbo.ProductsTable for dbo.Products_' + @lang)

/* Call the synonym table */
select top 10 * from dbo.ProductsTable
update ProductsTable set a = 'b'

我的问题是SQL Server在并发访问方面如何处理同义词?我担心程序可能会开始,然后是第二次出现并将同义词指向的表改为导致重大问题的中途。我可以将所有内容包装在BEGIN TRANCOMMIT TRAN中,理论上这应该可以消除两个进程更改同义词的风险,但是文档在这个问题上很少见,我无法得到明确的答案。

请注意,虽然这个系统是并发的,但流量并不高,所以使用同义词/事务的性能命中率并不是真正的问题。

感谢您的任何建议。

1 个答案:

答案 0 :(得分:1)

你的恐惧是正确的。同义词不打算以这种方式使用。包装它是一个事务(不确定需要什么样的隔离级别)可以解决问题,但只能使系统成为单用户。

如果我正在处理这个问题,那么我可能会使用动态SQL,因为我对它很熟悉。然而,考虑到它,我想知道模式是否可以解决您的问题 如果您为每种语言创建了模式,然后在每个模式中都有一个名为products的表。然后,您的存储过程可以引用非限定表名,SQL应该解析对当前用户的默认模式中的表的引用。然后,您需要更改应用程序验证的帐户,以确定它使用的架构,或者在存储过程中使用EXECUTE AS来确定哪个架构是默认的。
我没有测试过这个架构的想法,我可能没有想到所有的东西,我对你的应用程序知之甚少,不知道它是否真的可行。如果您决定尝试,请告诉我们。