Docker (Linux) 和 Windows 主机中 SQL Server 的 MSDTC 配置问题

Chr*_*eis 6 sql-server msdtc docker docker-compose sql-server-linux

我正在迁移本地 SQL Server 开发数据库以在 Linux docker 容器(在同一开发计算机上)中运行。在 Windows 上的 Visual Studio 2019 中运行集成测试时,我收到 MSDTC 错误:

抛出异常:System.Data.dll 中的“System.Transactions.TransactionManagerCommunicationException” System.Data.dll 中发生“System.Transactions.TransactionManagerCommunicationException”类型的异常,但未在用户代码中处理与底层事务管理器的通信失败。

这是我的 docker-compose 中 SQL Server 的最新版本:

services:
  sqlserver:
    image: mcr.microsoft.com/mssql/server:2019-latest
    container_name: SqlServer
    restart: always
    environment:
      - ACCEPT_EULA=Y
      - SA_PASSWORD=verySecretPassword
      - MSSQL_RPC_PORT=13500
      - MSSQL_DTC_TCP_PORT=51000
    ports:
      - "1401:1433"
      - "135:13500"
      - "51000:51000"
    volumes:
      - sqldata:/var/opt/mssql
Run Code Online (Sandbox Code Playgroud)

我尝试了各种方法来调整 RPC 端口以使其正常工作。这是 MS 的主要文章。我尝试过端口135:135但它给出了相同的错误。文章底部的注释似乎与我的问题有关。

对于容器外部的 SQL Server 或非根容器,必须在容器中使用不同的临时端口(例如 13500),并且必须将到端口 135 的流量路由到该端口。您还需要在容器内配置从容器端口 135 到临时端口的端口路由规则。

另外,如果您决定将容器的端口 135 映射到主机上的其他端口(例如 13500),则必须在主机上配置端口路由。这使得 docker 容器能够参与与主机和其他外部服务器的分布式事务。

SQL Server 2019 容器以非 root 用户身份运行。我已经尝试在 Windows 中使用 netsh 进行端口路由...并且 MS 文章链接到如何在 Ubuntu 中执行端口转发...即使在 SQL Server 容器中以 root 身份登录时我也无法执行此操作。 . iptables 没有安装,它不允许我apt-get install使用?我还更新了windows中的DTC选项,使其尽可能打开,但没有效果。不知道秘诀是什么。希望其他人也能有类似的设置。

MSDTC 选项

小智 0

感谢您提供有关配置的提示msdtc,我让我的工作与此组合一起工作:

version: '3.4'

services:
  sqlserver:
    image: mcr.microsoft.com/mssql/server:2019-GA-ubuntu-16.04
    container_name: sqlserver
    user: root
    environment:
      - ACCEPT_EULA=Y
      - SA_PASSWORD=[yourPwd]
      - MSSQL_RPC_PORT=135
      - MSSQL_DTC_TCP_PORT=51000
    ports:
      - "1433:1433"
      - "135:135"
      - "51000:51000"
    volumes:
      - D:\DockerVolumes\sqlserver:/var/opt/mssql/data
Run Code Online (Sandbox Code Playgroud)

  • 您确定 DTC 在这里起作用吗?主机不是也绑定到端口135(它是RPC端点管理器),因此无法与容器共享它吗?我们也正在努力让 DTC 在这里发挥作用。我们编写了一个在主机上运行的简单 DTC 测试器控制台应用程序。它尝试对容器中的 2 个独立数据库执行两个 TransactionScope 包装的更新命令。这会导致升级为分布式事务,并且失败并出现异常,表明无法将事务升级为分布式事务。 (2认同)