【问题标题】:SQL Server Synonyms and Concurrency Safety With Dynamic Table NamesSQL Server 同义词和动态表名的并发安全性
【发布时间】:2010-11-12 12:35:52
【问题描述】:

我正在使用一些商业模式,它们有一组相似的表,它们仅在语言名称上有所不同,例如:

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 中,理论上这应该消除两个进程更改同义词的风险,但是关于这件事的文档很少,我无法得到明确的答案。

请注意,虽然这个系统是并发的,但它的流量并不高,因此使用同义词/事务的性能损失在这里并不是真正的问题。

感谢您的任何建议。

【问题讨论】:

  • “商业模式”是什么意思?这是否意味着您不能修改数据库架构本身(即只能添加到其中)?
  • 它们是商业产品(Microsoft Commerce Server)的一部分,所以我可以添加它们,但我不能更改 API 依赖的约定或其他内容

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


【解决方案1】:

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

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

【讨论】:

  • 感谢您的回答。我也通常使用动态 SQL,但是有很多 SQL,我想确保它是可维护的,而不是到处都是 nvarchar 字符串,并且考虑到它对性能不是至关重要的,我将查看事务路由。你对模式的建议是一个非常有趣的建议,但是我需要相当多的时间来研究这个 - 但下次出现这个问题时我肯定会尝试!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
  • 1970-01-01
  • 2013-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多