错误消息 7391:链接服务器无法开始分布式事务(两个服务器都在本地运行)

8
我在我的Win 10 PC上,从SqlServer 2014设置了一个LinkedServer到运行在MySQL 5.7.3上的MySQL。通过openquery,选择和插入查询都可以正常工作,但插入查询在触发器中无法正常工作。请不要将此标记为重复,除非您找到尚未列在下面的“治愈”! OLE DB提供程序“MSDASQL”用于链接服务器“MYSQL”返回消息“[MySQL] [ODBC 5.3(w)驱动程序]不支持的可选功能”。 Msg 7391,Level 16,State 2,Procedure TRG_AfterEventInsert,Line 14 无法执行操作,因为链接服务器“MYSQL”的OLE DB提供程序“MSDASQL”无法开始分布式事务。
有很多关于这个问题的帖子,但我已经做了我能找到的一切,它仍然无法工作。我找到了一个名为dtcping的MS实用程序,它一开始失败,直到我翻转了一个注册表设置,但现在它成功了。
在DTC属性屏幕上,我启用了Network DTC Admin,允许远程,允许输入/出站而不需要身份验证,并启用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“事务正在中止”
3个回答

1

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


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]" 语法,请求 Provider MSDASQL 启用 Level 0 only 设置(转到链接服务器并在提供程序上设置)。
但是,正如其他人建议的那样,您可能最好只需从触发器中启动作业。
完整测试代码:
---------------
-- 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]


0
你是指 MySQL 5.3 吗?当前的手册显示版本低至 5.7,并指出分布式事务仅支持 InnoDB 存储引擎 14.3.7 XA Transactions
如果你已经检查了所有关于 MySQL 的部分,那么你是否在 SQL Server 端使用了不同类型的触发器?或者你可能正在使用不受支持的数据类型吗?

抱歉...版本中有错别字,应该是5.7,而且我肯定使用的是InnoDB存储。触发器是“插入后”,我只是运行了与我的正常SQL会话中运行良好的相同插入查询。 - DeannaD

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

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

所以你需要使用DTC或者从触发器中调用链接服务器中使用(2)


我正在尝试使用DTC。链接中的替代方法不好用。我无法从SQLSVR复制到MYSQL,并且安排任务会导致延迟。 - DeannaD
@DeannaD,在评论中我提到并不需要等待任务被计划触发,你可以从触发器开始启动作业,这样延迟将会最小化,并且记录将几乎立即得到处理。另外,你也可以连续运行作业,每隔X毫秒检查一次表格。 - Anton
@DeannaD,关于复制,有各种客户(非本地)解决方案可以从MSSQL复制到MySQL,例如http://www.symmetricds.org/。 - Anton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接