4

我正在尝试测试一个概念证明,即我可以在两个链接的 SQL Server 上运行分布式事务,使用 sp_addlinkedserver 链接 - 它们的名称是 Server1 和 Server2,两者都在默认实例下运行。每个服务器分别拥有一个数据库,Source 和 Destination,目标数据库拥有一个名为 Output 的表,即

Server1.Source
Server2.Destination.Output

OUTPUT 表具有以下结构:

OUT_PKEY int identity(1,1) primary key,
OUT_TEXT nvarchar(255)

在 Server1 中,我调用sp_addlinkedserver 'Server2'来链接两个数据库,并尝试运行以下查询来测试该链接是否确实有效:

Select   *
From     Server2.Destination.dbo.Output

我返回以下异常:

对远程服务器的访问被拒绝,因为不存在登录映射。

很公平,所以我从 Server1 运行sp_addlinkedsrvlogin 'Server2',根据文档,它应该获取远程运行查询的用户凭据(即来自 Server1)并将这些凭据应用于 Server2。这意味着由于我使用 Windows 身份验证连接到 Server1,这应该意味着我的 Windows 凭据也适用于 Server2。

现在异常消息变为:

用户“NT AUTHORITY\ANONYMOUS LOGON”登录失败。

在谷歌上搜索了这个异常后,我没有找到任何有用的东西来指引我正确的方向。我错过了什么?我希望 [如果登录失败] 异常引用我的Windows 凭据,而不是匿名登录凭据。

看起来一旦我让链接本身工作,分布式事务本身应该是一件相当简单的事情 - 文档暗示我只需要确保 DTC 服务在 Server1 上运行,并且任何查询都在 Server1 上运行,将被处理通过链接:

  • 在初始化我的分布式事务之前包括SET XACT_ABORT ON
  • 我使用BEGIN DISTRIBUTED TRANSACTION而不是BEGIN TRANSACTION
  • 如果我希望在 Server2 上引用 SQL Server 的非默认实例,我将查询中名称Server2的任何实例替换为[Server2\InstanceName]

我的问题是:

  • 我该如何解决这个登录问题?单独的sp_addlinkedsrvlogin存储过程似乎并不能解决问题。
  • 运行分布式事务真的像文档所暗示的那样简单吗?

TIA

4

2 回答 2

1

如果您在域中,则设置应为“使用登录的当前安全上下文进行”,但还有一个步骤 - 您需要向事务中涉及的每个服务器授予 SPN。

假设您以域用户身份在两台服务器上运行 SQL 服务(您需要这样做 - LocalSystem 不会这样做),以下是您需要的说明:

http://technet.microsoft.com/en-us/library/bb735885.aspx

请记住,用户将需要两个服务器的 SPN,而不是客户端 - 例如,如果您从客户端 -> 服务器 1 - > 服务器 2,SQL 服务帐户将需要服务器 1 和服务器 2 的 SPN。

如果您感到困惑(这是一个令人困惑的过程),请发表评论,我会澄清说明。

于 2009-01-16T18:14:03.663 回答
0

假设这些服务器都在同一个域上 - 您是否启用了受信任的委派以允许您的服务器将凭据传递给目标服务器?您将提取服务器的 Active Directory 对象并转到“委派”选项卡并选择“仅信任此计算机以委派给指定的服务”,然后输入允许服务器将凭据传递到的 SQL Server 详细信息:

服务类型 = MSSQLSvc
用户/计算机 = YourTargetServer.Your.Domain
端口 = 1433

可悲的是,链接服务器的许多此类身份验证问题需要重新启动才能完全生效(因此,如果这些是生产服务器,则很难在白天进行故障排除)。

关于分布式事务-如果您最终使链接服务器连接正常运行,那么分布式事务就可以很好地工作。虽然一旦你开始工作,你可能会遇到的下一件事是发现一个巨大的缺陷,即你不能使用任何形式的 SCOPE_IDENTITY()、@@IDENTITY 等在将某些内容插入链接数据库后检索主键. 但这是另一个有趣的解决方法的问题......

于 2009-01-16T17:59:00.727 回答