如何在使用TransactionScope时配置MySQL进行回滚?

时间:2012-11-15 09:44:18

标签: c# mysql transactionscope

我花了一周时间尝试让我的MySQL数据库处理事务。仍然没有成功。正在运行Windows 7 x64MySQL Server 5.6.7-rcMySQL .NET Connector 6.6.4

MySQL声称支持TransactionScope(我现在已经阅读了整个互联网),所以我猜我需要某种特殊的配置才能让它正常工作。这是我到目前为止所尝试的内容:

自动提交= 0

  • my.ini我已在autocommit=0部分下方添加了[mysqld]
  • my.ini我已在init_connect='SET autocommit=0'部分下方添加了[mysqld]
  • 在Service Manager中,我添加了--autocommit=0作为命令行参数。
  • 我已经确认SELECT @@autocommit返回0。

的sql_mode =作者

  • my.ini我已在sql-mode="TRADITIONAL"部分下方添加了[mysqld]
  • 在Service Manager中,我添加了--sql-mode=TRADITIONAL作为命令行参数。

分布式事务处理协调器

  • 我尝试启用/禁用DTC服务。

下面的示例在调用System.Transactions.TransactionException时会立即引发异常(必须通过Ctr + Alt + E启用Open()例外)。错误消息该操作对事务状态无效。。显然,服务器对事务的东西不满意 - 事实证明,不会发生回滚。

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();
}

示例代码适用于SQL Server,因此我确信此问题与MySQL有关。

问题:我已经尝试了一切。我需要做些什么才能使TransactionScope代码适用于MySQL

1 个答案:

答案 0 :(得分:0)

MySQL将在执行DDL语句时自动提交活动事务(请参阅http://dev.mysql.com/doc/refman/5.5/en/cannot-roll-back.html)。因此,CREATE TABLE之后的任何内容都不会成为事务的一部分。

如果您按如下方式执行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();
}