【问题标题】:Msg 7391: linked server unable to begin a distributed transaction (both svrs running locally)消息 7391:链接服务器无法开始分布式事务(两个 svrs 在本地运行)
【发布时间】:2017-01-18 14:42:13
【问题描述】:

我将 LinkedServer 从 SqlServer 2014 设置为在我的 Win 10 PC 上运行的 MySQL 5.7.3。选择和插入查询都可以通过 openquery 单独工作,但插入查询不会在触发器中起作用。请不要将此标记为重复,除非您找到下面未列出的“治疗”!

链接服务器“MYSQL”的 OLE DB 提供程序“MSDASQL”返回消息“[MySQL][ODBC 5.3(w) Driver]Optional feature not supported”。

*消息 7391,级别 16,状态 2,过程 TRG_AfterEventInsert,第 14 行

无法执行操作,因为链接服务器“MYSQL”的 OLE DB 提供程序“MSDASQL”无法开始分布式事务。

关于这方面的帖子有很多,但我已经做了我能找到的所有事情,但它仍然无法正常工作。我发现了一个名为 dtcping 的 MS 实用程序,它起初失败,直到我翻转了注册表设置,但现在它成功了。

在 DTC 属性屏幕上,我启用了网络 DTC 管理员、允许远程、允许输入/出站而无需身份验证和启用 XA 事务。在我的链接服务器上,我有 rpc & rpc out = true 并且“启用 DT 提升”为 false。我将 msdtc 应用添加到防火墙排除项中。

我还尝试为我的 LinkedServer 禁用 DTC,但没有奏效。我仍然得到错误。

任何人都可以在这里提出调试措施吗?我花了几乎一整天的时间在这上面没有成功。 MySQL驱动是5.3(32位)。

更新: dtcPing 运行没有错误,但是当我尝试触发插入时,我在 dtctrace.log 中看到以下内容

TRANSACTION_BEGUN RM_ENLISTED_IN_TRANSACTION "资源管理器 #1001 作为事务登记 #1 登记。RM guid = '57c2b4b4-f37a-4017-a1fc-2d95bd64693d'"

RECEIVED_ABORT_REQUEST_FROM_BEGINNER "收到初学者中止交易的请求"

TRANSACTION_ABORTING "事务正在中止"

【问题讨论】:

    标签: mysql sql-server msdtc


    【解决方案1】:

    你的意思是 MySQL 5.3 吗?当前手册显示版本低至 5.7,并指出分布式事务仅支持 InnoDB 存储引擎14.3.7 XA Transactions

    如果您已经检查了 MySQL 部分的所有内容,您是否检查过 SQL Server 端的不同类型的触发器?您是否使用了不受支持的数据类型?

    【讨论】:

    • 抱歉...在 5.7 版本中出现错字,是的,我肯定在使用 InnoDB 存储。触发器是“插入后”,我只是运行在我的正常 SQL 会话中运行良好的相同插入查询。
    【解决方案2】:

    "包裹在触发器中的分布式查询,即使没有 明确指定的事务,也被视为分布式 交易。”

    support.microsoft.com/en-us/kb/274348

    所以您需要使用 DTC 或使用来自 Calling linked server from trigger 的 (2)

    【讨论】:

    • 我正在尝试使用 DTC。链接中的替代方法不好。我无法从 SQLSVR 复制到 MYSQL,调度任务会导致延迟。
    • @DeannaD,在我提到的cmets中,不需要等到任务被调度触发,你可以从触发器开始一个工作,所以延迟最小并且记录将被处理几乎立即。或者,您可以连续运行作业,每 X 毫秒检查一次表格。
    • @DeannaD,至于复制,有各种客户(非本地)解决方案可以从 MSSQL 复制到 MySQL,例如symmetricds.org
    【解决方案3】:

    创建触发器时,请使用以下构造来避免事务:

    
    create trigger ti on t for insert, update as
    begin
    
        COMMIT -- Commit FIRST to avoid DTC...
        insert into  [mysql]...[mysql.customers] (a,b) -- Do you work
        select  i, 'Test'
        from    inserted
        BEGIN TRAN -- Start tran again otherwise it will crash!!
    end
    go
    

    注意,“[mysql]...[mysql.customers]”语法,请求提供者 MSDASQL 启用仅级别 0 设置(转到链接服务器并在提供者上设置)。

    但正如其他人所建议的那样,你最好还是直接从触发器中踢出一份工作。

    完整的测试代码:

    ---------------
    -- Run on MYSQL...
    ---------------
    CREATE TABLE customers (a INT, b CHAR (20), INDEX (a)) ENGINE=InnoDB;
    
    ---------------
    -- Run on SQL Server
    ---------------
    create table t (i int)
    
    go
    
    create trigger ti on t for insert, update as
    begin
    
        COMMIT -- Commit tran to avoid DTC...
        insert into  [mysql]...[mysql.customers] (a,b)
        select  i, 'Test'
        from    inserted
        begin tran -- Start tran again otherwise it will crash!
    end
    go
    
    insert into t (i) select 1
    
    -- Verify results
    select *
    from [mysql]...[mysql.customers]
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-21
      • 2013-09-10
      • 2011-11-20
      • 2015-01-10
      • 2017-09-19
      • 1970-01-01
      相关资源
      最近更新 更多