Microsoft SQL Server 和 MariaDB 之间的分布式事务 - 一个神话






4.92/5 (3投票s)
MS SQL Server 和 MariaDB 之间的分布式事务 - 一个神话。
- 下载 LinkedServer_MariaDB_AutoGen_Script.zip - 772 B
- 下载 Distributed_Transactions_Involving_MSSQL_MariaDB.zip - 3 KB
介绍
MariaDB 是 MySQL 的直接替代品。它由 Monty Widenius 和他的团队(MySQL 的创建者)创建。许多科技巨头,如 Google、RedHat、Wikimedia 等,因其技术优势已从 MySQL 迁移到 MariaDB(参见:链接)。
因此,MariaDB 现在是一个热门话题,而 MariaDB 与著名的 Microsoft SQL Server 之间的分布式事务是一个迫切需要解决的问题。本文提供了进行的试验/实验以及证明 MariaDB 与 Microsoft SQL Server 之间分布式事务是神话的链接。
注意:由于 MySQL 和 MariaDB 的开发者相同,它们的内部架构相似,迁移工作并不困难。
背景
Google 从 MySQL 迁移到 MariaDB,并投入一名工程师进行 MariaDB 开发,这使得 MariaDB 名声大噪。我发布本文的主要原因是,互联网上有很多信息,但只有极少数能真实地讲述涉及 MariaDB 和 MS SQL Server 的分布式事务的真相。
进行的实验
进行此实验前安装的软件列表(先决条件):
- Microsoft SQL Server 2008 R2
- MariaDB 5.5.33a – x86
- MySQL 的 ADO.NET 驱动程序(mysql-connector-net-6.7.4.msi)[稍后在此文档中解释用途] – x86
- Windows 的 ODBC 驱动程序 – x64(mysql-connector-odbc-5.2.5-winx64.msi)[稍后在此文档中解释用途]
进行的实验
- 尝试 1 – 从 MSSQL Server
- 尝试 2 – 从 .NET (代码) – Transaction Scope
- 尝试 3 – 从 .NET (代码) – 带有两阶段提交的 Transaction Scope
- 使用 AutoEnlist 关键字
尝试 1 – 从 MS SQL Server
第一次分布式事务尝试是使用 MS SQL Server 2008 R2 和流行的“链接服务器”概念进行的。要链接 MariaDB 服务器,我们需要一个驱动程序:“Windows 的 ODBC 驱动程序 – x86(mysql-connector-odbc-5.2.5-winx64.msi)”。
您需要安装此驱动程序并配置数据源。这可以通过“开始 -> 控制面板 -> 所有控制面板项 -> 管理工具 -> 数据源 (ODBC)”完成。使用安装的驱动程序(Unicode 或 ANSI 版)在那里添加“系统 DSN”。
添加数据源后,我们需要创建一个链接服务器。创建过程在单独的附件中。或者,您可以使用“MS SQL SERVER 2008 R2 -> 对象资源管理器 -> 服务器对象 -> 链接服务器”来创建一个。
现在我尝试使用 MSSQL 和 MariaDB 之间的分布式事务创建存储过程,却发现 MSSQL 抛出错误。
OLE DB provider "MSDASQL" for linked server "MARIADB" returned message
"[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified".
Msg 7303, Level 16, State 1, Procedure Proc_test_distributedtrans_sql_mariadb_ins, Line 21
Cannot initialize the data source object of OLE DB provider "MSDASQL" for linked server "MARIADB".
尝试 2 – 从 .NET (代码) – Transaction Scope:
现在引入了 .NET 平台。
(需要 MySQL 的 ADO.NET 驱动程序(mysql-connector-net-6.7.4.msi)。安装后,将名为“MySql.Data.dll”的 dll 添加到项目的引用中,并导入它。)
建立了 TransactionScope
,并组合了两个连接字符串:一个 MSSQL 连接和一个 MariaDB 连接。在这里,在代码执行期间,打开 MSSQL 或 MySQL(MariaDB)连接时不会有问题,但一旦在单个事务中打开第二个连接(即使第一个连接已关闭),就会抛出如下所示的错误。
“System.NotSupportedException was caught Message=Specified method is not supported.” (Or) “MySQL Connector/Net does not currently support distributed transactions.”
尝试 3 – 从 .NET (代码) – 带有两阶段提交的 Transaction Scope
(也需要 MySQL 的 ADO.NET 驱动程序(mysql-connector-net-6.7.4.msi))此方法与上述方法类似,因为它也在此 TransactionScope
下运行,但执行“两阶段提交”。一个称为“准备”阶段,另一个称为“提交”阶段。其源代码在附件中提供。
结果也类似,都是相同的失败和相同的错误。
“System.NotSupportedException was caught Message=Specified method is not supported.” (Or) “MySQL Connector/Net does not currently support distributed transactions.”
使用 AutoEnlist 关键字
通过深入搜索可以找到这个关键字,但有时会被误解。
有关此内容,请参阅 MySQL 文档。如果您仅执行 MySQL(MariaDB)事务,并且抛出相同的错误
“MySQL Connector/Net does not currently support distributed transactions”
则可以使用此 AutoEnlist
并将其设置为 false,以使编译器理解您执行的不是不同数据库之间的分布式事务。
现在,如果您在我们(涉及不同数据库的分布式事务)的情况下使用此关键字,您将成功执行程序而没有错误,但事务的目的将失败。一旦 AutoEnlist
被编译,= false
TransactionScope
将排除该 MariaDB
批处理,并且在 ExecuteNonQuery()
语句处将提交其结果。它不会等待 Scope 对象引发 Complete()
方法。
推断内容
从上述尝试/实验中可以明显看出,**MariaDB(MySQL)数据库不允许分布式事务**。(即使 Microsoft 分布式事务协调器正在运行)。
在 这里 MySQL 网站本身就说明了 MySQL(MariaDB)不允许“分布式事务”。并且在 MySQL 6.1 alpha 版本中也没有修复。
(请参阅名为“[11 Jun 2008 12:01] Cyrille Giquello”的评论及之后的评论。)
值得关注的点
我学到了重要的一点,不仅 MariaDB(MySQL)和 MS SQL 之间**不支持分布式事务**,**而且通常也不应该使用分布式事务**。以下是一些建议通常不使用“分布式事务”的链接。它们强调的主要原因是网络问题,可能导致事务非原子性,这根本不是事务。
- http://stackoverflow.com/questions/128377/what-is-the-best-way-to-do-distributed-transactions-across-multiple-databases
- http://c2.com/cgi/wiki?DistributedTransactionsAreEvil
历史
我将在下一篇文章中上传 MySQL 到 MariaDB 的迁移过程。我本应先做那个,但由于这个主题引起了我的极大兴趣,所以我先发布了这篇。