C# 如何配置MySQL在使用TransactionScope时回滚?

C# 如何配置MySQL在使用TransactionScope时回滚?,c#,mysql,transactionscope,C#,Mysql,Transactionscope,我花了一周的时间试图让我的MySQL数据库的事务正常工作。仍然没有成功。运行Windows7x64,MySQL服务器5.6.7-rc和MySQL.NET连接器6.6.4 MySQL声称支持TransactionScope(我现在已经阅读了整个互联网),所以我猜我需要某种特殊的配置来让它工作。以下是我迄今为止所尝试的: 自动提交=0 在my.ini中,我在[mysqld]部分下面添加了autocommit=0 在my.ini中,我在[mysqld]部分下面添加了init\u connect='S

我花了一周的时间试图让我的MySQL数据库的事务正常工作。仍然没有成功。运行
Windows7x64
MySQL服务器5.6.7-rc
MySQL.NET连接器6.6.4

MySQL声称支持
TransactionScope
(我现在已经阅读了整个互联网),所以我猜我需要某种特殊的配置来让它工作。以下是我迄今为止所尝试的:

自动提交=0

  • my.ini
    中,我在
    [mysqld]
    部分下面添加了
    autocommit=0
  • my.ini
    中,我在
    [mysqld]
    部分下面添加了
    init\u connect='SET autocommit=0'
  • 在Service Manager中,我添加了
    --autocommit=0
    作为命令行参数
  • 我已验证
    SELECT@@autocommit
    是否返回0
sql\u模式=传统

  • my.ini
    中,我在
    [mysqld]
    部分下面添加了
    sql mode=“TRADITIONAL”
  • 在Service Manager中,我添加了
    --sql mode=TRADITIONAL
    作为命令行参数
分布式事务协调器

  • 我已尝试启用/禁用DTC服务
下面的示例在调用
Open()
时立即抛出异常(
System.Transactions.TransactionException
异常必须通过Ctr+Alt+E启用)。错误消息为该操作对于事务状态无效。。显然,服务器对事务内容不满意——这一点可以通过没有发生回滚的事实来证明

var factory = System.Data.Common.DbProviderFactories.GetFactory("MySql.Data.MySqlClient");

using (var transaction = new System.Transactions.TransactionScope())
{
    var connection = factory.CreateConnection();
    connection.ConnectionString = "Server=localhost;Port=3306;Database=test;User ID=user;Password=user";
    connection.Open(); // <-- silent TransactionException here!

    var command = connection.CreateCommand();
    command.CommandText = "CREATE TABLE TestTable (ID INT) ENGINE = InnoDB DEFAULT CHARSET=utf8;";

    command.ExecuteNonQuery();

    command.CommandText = "INSERT INTO TestTable (ID) VALUES (123);";
    command.ExecuteNonQuery();

    // ATTENTION! This should imply a rollback!
    // transaction.Complete();
}
var factory=System.Data.Common.dbProviderFactorys.GetFactory(“MySql.Data.MySqlClient”);
使用(var transaction=new System.Transactions.TransactionScope())
{
var connection=factory.CreateConnection();
connection.ConnectionString=“服务器=本地主机;端口=3306;数据库=测试;用户ID=用户;密码=用户”;

connection.Open();//MySQL将在执行DDL语句时自动提交活动事务(请参阅)。因此创建表之后的任何内容都不会成为事务的一部分

如果按如下方式执行SQL语句,也会发生同样的情况:

START TRANSACTION;
CREATE TABLE TestTable (ID INT) ENGINE = InnoDB DEFAULT CHARSET=utf8;
INSERT INTO TestTable (ID) VALUES (123);
ROLLBACK;
尝试将代码更改为:

var factory = MySqlClientFactory.Instance;
string connectionString = "Server=localhost;Port=3306;Database=test;User ID=user;Password=user";

// DDL cannot be performed in transaction as will commit
using (var connection = factory.CreateConnection())
{
    connection.ConnectionString = connectionString;
    connection.Open();

    var command = connection.CreateCommand();
    command.CommandText = "CREATE TABLE TestTable (ID INT) ENGINE = InnoDB DEFAULT CHARSET=utf8;";
    command.ExecuteNonQuery(); // will always commit here
}

// DML can be performed in transaction
using (var transaction = new System.Transactions.TransactionScope())
using (var connection = factory.CreateConnection())
{
    connection.ConnectionString = connectionString;
    connection.Open();   

    var command = connection.CreateCommand();
    command.CommandText = "INSERT INTO TestTable (ID) VALUES (123);";
    command.ExecuteNonQuery();

    // should rollback here
    //transaction.Complete();
}

您所说的是正确的。但是,最新版本的
MySQL.NET连接器
不支持与
SQL Server
相同(极好)的事务作用域。更具体地说,创建嵌套连接(这对于连接-执行-断开应用程序很有意义)产生问题。我不确定上面需要嵌套连接的位置。如果将每个SQL命令包装在connect execute disconnect(如上所述)中,则永远不会嵌套,对吗?如果您有多个带有事务的API,则最终会出现嵌套连接:
GetDocumentsUsingTransaction(){…GetTextUsingTransaction()…}