0

此代码有效:

CREATE SYNONYM S FOR [ServerIP].[MyDatabase].[dbo].[MyTable]
SELECT * FROM S
DROP SYNONYM S

而这个是行不通的。

BEGIN TRAN              
    CREATE SYNONYM S FOR [ServerIP].[MyDatabase].[dbo].[MyTable]
    SELECT * FROM S
    DROP SYNONYM S
COMMIT TRAN

我在执行 SELECT 语句时获得排他锁(request_mode 为 X),resource_type = KEY 在 sysschobjs 和 sysobjvalues 上。

谁能解释它为什么会挂掉?

PS 该示例只是更复杂代码的简化,其中外部事务在调用者 SP 中调用。

4

1 回答 1

0

我认为问题可能在于同义词可以在事务范围之外访问(以及当前连接)。尝试在 SSMS 的不同选项卡中运行两组代码。

会发生什么,另一个选项卡中的第二个查询将等待 10 秒,直到第一个查询完成:

-- first tab:
    BEGIN TRAN              
        CREATE SYNONYM S FOR [ServerIP].[MyDatabase].[dbo].[MyTable]
        waitfor delay '00:00:10'
        SELECT * FROM S
        DROP SYNONYM S
    COMMIT TRAN

-- second tab:
BEGIN TRAN              
    CREATE SYNONYM S FOR [ServerIP].[MyDatabase].[dbo].[MyTable]
    SELECT * FROM S
    DROP SYNONYM S
COMMIT TRAN

当您运行这些查询时,第二个将在CREATE语句上失败,但随后将从 select 返回行,并且不会等待事务提交:

-- first tab:
CREATE SYNONYM S FOR [ServerIP].[MyDatabase].[dbo].[MyTable]
waitfor delay '00:00:10'
SELECT * FROM S
DROP SYNONYM S

--second tab:
CREATE SYNONYM S FOR [ServerIP].[MyDatabase].[dbo].[MyTable]
SELECT * FROM S
DROP SYNONYM S

防止多个会话尝试删除并创建相同同义词的可能解决方案:

  1. 不要使用同义词:)
  2. 首先检查同义词是否存在(尽管不能保证具有该特定名称的同义词指向正确的表): if not exists(select * from sys.synonyms where name = 's') create synonym s for [MyDatabase].[dbo].[MyTable]
  3. 创建将由过程的每个实例使用的永久同义词
于 2013-10-30T17:59:06.960 回答