我花了一周时间尝试让我的MySQL数据库处理事务。仍然没有成功。正在运行Windows 7 x64
,MySQL Server 5.6.7-rc
和MySQL .NET Connector 6.6.4
。
MySQL声称支持TransactionScope
(我现在已经阅读了整个互联网),所以我猜我需要某种特殊的配置才能让它正常工作。这是我到目前为止所尝试的内容:
自动提交= 0
my.ini
我已在autocommit=0
部分下方添加了[mysqld]
。my.ini
我已在init_connect='SET autocommit=0'
部分下方添加了[mysqld]
。--autocommit=0
作为命令行参数。SELECT @@autocommit
返回0。的sql_mode =作者
my.ini
我已在sql-mode="TRADITIONAL"
部分下方添加了[mysqld]
。--sql-mode=TRADITIONAL
作为命令行参数。分布式事务处理协调器
下面的示例在调用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
?
答案 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();
}