在事务中使用MySqlCommand的MySqlBulkLoader

时间:2016-06-07 15:15:18

标签: c# mysql transactions mysql-connector

我有一个MySql数据库,里面有九个表。我需要从C#中的异步作业动态上传到其中的六个。但是,为了加速上传,其中四个使用MySqlBulkLoader,而另外两个使用手动上传方法。为了支持并发性并防止数据库中的错误,我需要同时上传它们。为此,我决定使用交易来确保“全部或全部”类型上传。

存在的问题是:MySqlCommand类允许通过MySqlTransaction属性中的Transaction类进行事务支持,MySqlBulkLoader允许原子上传(我使用)引擎INNODB,请参阅mysql - Can MySqlBulkLoader be used with a transaction?)。但是,MySqlBulkLoader创建了自己的原子上传事务,而另一个单独的事务将用于我将执行的MySqlCommand。这不支持序列化,如果一个批量加载器完成它的工作,仍然可能导致错误,但应用程序在另一个完成之前关闭。如果交易可以嵌套,这将是可解决的;但是,他们不能:php - Mysql transactions within transactions

我的问题如下:C#连接器中是否有任何方法允许MySqlBulkLoaderMySqlTransaction相关联,如果没有,是否有任何方法可以自动回滚所做的更改之前的MySqlBulkLoader。我查看了Connector.NET 6.9提供的API,看起来这可能是通过MySqlConnection.BeginTransaction()方法实现的,但是来自Werner Wolf的问题建议不这样做。

修改

我在this question找到了Saravanan。但是,我不认为这个问题与MySqlBulkLoaderMySqlCommand混合的因素有关。

1 个答案:

答案 0 :(得分:1)

原始问题提出:

C#连接器中是否有任何方法允许MySqlBulkLoaderMySqlTransaction
相关联 为此,似乎没有。将两个事务放在一起也不起作用,因为它不支持序列化(因为我认为它不会)。但是,另一个问题是:
是否有任何方法可以自动回滚先前MySqlBulkLoader所做的更改。
而且,似乎没有一种简单的方法可以回滚这些变化。当然,我可以检查之前和之后的表状态,删除之前不存在的条目;但是,这种解决方案并不是最佳的。但是,解决方案可能以问题的形式出现。原始问题的答案假定无法将单独的交易与MySqlBulkLoader相关联;但是没有指定我们可以自己创建一个(a.k.a。,扩展MySqlBulkLoader类以包含Transaction实例参数)。这似乎是问题的解决方案,也是Werner Wolf问题的解决方案。

然而,这根本不是解决方案。由于MySqlBulkLoader是SQL LOAD DATA INFILE语法的简单包装器,因此它的行为与SQL查询一样。从MySQL Reference Manual开始,我们得到了答案:

本节中列出的语句(以及它们的任何同义词)隐式结束当前会话中活动的任何事务,就好像您已经完成了执行语句之前执行COMMIT。
网页部分中较低的语句为LOAD DATA INFILE。这是我们问题的真正答案:不可能将MySqlBulkLoaderMySqlTransaction相关联,至少可以使它按照我们想要的方式运作。然而,如上所述,问题的解决方案可能是检查每个表的主键的索引,锁定表,保存它们的位置,并进行手动"回滚"上传失败后。