【问题标题】:How can I use transactions that span procedures chained across multiple servers?如何使用跨多个服务器链接的过程的事务?
【发布时间】:2010-10-01 16:40:53
【问题描述】:

我正在尝试测试我们的一个供应商为访问他们的产品数据库而向我们提出的命题,该命题涉及跨多个服务器的查询和事务。我以前从来没有直接在数据库上做过这个,坦率地说,我一无所知,所以我试图模拟一个证明,证明这至少在概念上是有效的。

我有两台 SQL Server 2005 服务器。为了争论,我们称它们为 Server1 和 Server2 [保持你的掌声] 每个都包含一个虚拟数据库。 Server1 上的虚拟数据库称为 Source,Server2 上的虚拟数据库称为 Destination,只是为了简单起见。每个数据库都有一个单独的表,分别称为 Input 和 Output,因此该结构准解释如下:

  • Server1.Source.dbo.Input
  • Server2.Destination.dbo.Output

我在 Server2 上有一个名为 WriteDataToOutput 的存储过程,它接收单个 Varchar 参数并将其内容写入输出表。

现在开始棘手了:

  1. 我想在 Server1.Source 上创建一个存储过程,它调用在 Server2 上定义的 WriteDataToOutput 存储过程,这似乎是一个简单的步骤。
  2. 我希望此调用成为事务的一部分,以便在调用它的过程失败时,回滚整个事务。

至此,我不知道该做什么了。谁能指出我正确的方向?我在同一台服务器上的两个不同数据库上试过这个,它工作得很好,让我假设它可以在不同的服务器上工作,问题是,我该怎么做这样的事情?我从哪里开始?

【问题讨论】:

    标签: sql-server-2005 tsql transactions


    【解决方案1】:

    正如其他人所指出的,我同意链接服务器是最好的选择。

    以下是我第一次处理链接服务器时的一些提示:

    • 如果链接服务器是实例,请确保将名称括起来。例如 [SERVERNAME\INSTANCENAME]。

    • 为链接服务器中的表或视图使用别名,否则您将收到“无法绑定多部分标识符”错误。有 4 部分命名约定的限制。例如 SERVER.DATABASE.dbo.TABLE.FIELD 有五个部分,会报错。但是,SELECT linked.FieldName FROM SERVER.DATABASE.dbo.TABLE AS linked 可以正常工作

    【讨论】:

    • +1 感谢您指出可能的陷阱和解决方案
    【解决方案2】:

    【讨论】:

    • 或者,您可以只创建一个 DTS/SSIS 包。
    • @Dalin - 可以从查询/存储过程中触发 DTS/SSIS 包吗?如果可以,如果事务失败可以回滚吗?
    【解决方案3】:

    对于第 2 步,您需要运行分布式事务协调器,您还需要使用 SET XACT_ABORT ON 来确保它会全部回滚 您还需要启用 2005 年及更高版本默认关闭的 RPC

    有一大堆东西可以咬你的脖子

    【讨论】:

      【解决方案4】:

      MSDN 表示,如果您使用命令 BEGIN DISTRIBUTED TRANSACTION,您可以跨链接服务器进行交易。

      我记得虽然我在链接服务器上遇到了称为存储过程的问题,但我解决了它,而不是解决它。

      【讨论】:

        【解决方案5】:

        使用链接服务器,您可以使用 DTC(分布式事务处理协调器)在单个事务中在任一服务器上运行存储过程。你肯定会想做一些性能分析。我发现一些使用链接的 SP 会大大降低数据库性能,尤其是当您尝试从两台服务器中的每台连接结果集时。

        【讨论】:

        • +1 感谢您的建议,我正在考虑使用它将某些财务数据从运营数据库推送到财务数据库。因此,不需要跨数据库连接。
        【解决方案6】:

        设置链接服务器,然后您应该能够跨服务器执行选择/插入/更新。比如:

        INSERT INTO Server2.Destination.dbo.Output
        SELECT * FROM Input  
        WHERE <Criteria>
        

        这假设您正在从 Server1.Source 运行查询,因此您不需要完全限定。

        【讨论】:

        • 我将调用在 Server2.Destination 上定义的存储过程
        • 别忘了他要回滚一切,所以你需要运行DTC,SET XACT_ABORT ON
        猜你喜欢
        • 2013-10-14
        • 1970-01-01
        • 2011-03-03
        • 1970-01-01
        • 2015-01-07
        • 1970-01-01
        • 2013-02-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多