我有一个MySql数据库,里面有九个表。我需要从C#中的异步作业动态上传到其中的六个。但是,为了加速上传,其中四个使用MySqlBulkLoader
,而另外两个使用手动上传方法。为了支持并发性并防止数据库中的错误,我需要同时上传它们。为此,我决定使用交易来确保“全部或全部”类型上传。
存在的问题是:MySqlCommand
类允许通过MySqlTransaction
属性中的Transaction
类进行事务支持,MySqlBulkLoader
允许原子上传(我使用)引擎INNODB
,请参阅mysql - Can MySqlBulkLoader be used with a transaction?)。但是,MySqlBulkLoader
创建了自己的原子上传事务,而另一个单独的事务将用于我将执行的MySqlCommand
。这不支持序列化,如果一个批量加载器完成它的工作,仍然可能导致错误,但应用程序在另一个完成之前关闭。如果交易可以嵌套,这将是可解决的;但是,他们不能:php - Mysql transactions within transactions。
我的问题如下:C#连接器中是否有任何方法允许MySqlBulkLoader
与MySqlTransaction
相关联,如果没有,是否有任何方法可以自动回滚所做的更改之前的MySqlBulkLoader
。我查看了Connector.NET 6.9提供的API,看起来这可能是通过MySqlConnection.BeginTransaction()
方法实现的,但是来自Werner Wolf的问题建议不这样做。
修改
我在this question找到了Saravanan。但是,我不认为这个问题与MySqlBulkLoader
与MySqlCommand
混合的因素有关。
答案 0 :(得分:1)
原始问题提出:
C#连接器中是否有任何方法允许相关联 为此,似乎没有。将两个事务放在一起也不起作用,因为它不支持序列化(因为我认为它不会)。但是,另一个问题是:MySqlBulkLoader
与MySqlTransaction
是否有任何方法可以自动回滚先前MySqlBulkLoader
所做的更改。
而且,似乎没有一种简单的方法可以回滚这些变化。当然,我可以检查之前和之后的表状态,删除之前不存在的条目;但是,这种解决方案并不是最佳的。但是,解决方案可能以问题的形式出现。原始问题的答案假定无法将单独的交易与MySqlBulkLoader
相关联;但是没有指定我们可以自己创建一个(a.k.a。,扩展MySqlBulkLoader
类以包含Transaction
实例参数)。这似乎是问题的解决方案,也是Werner Wolf问题的解决方案。
然而,这根本不是解决方案。由于MySqlBulkLoader
是SQL LOAD DATA INFILE
语法的简单包装器,因此它的行为与SQL查询一样。从MySQL Reference Manual开始,我们得到了答案:
本节中列出的语句(以及它们的任何同义词)隐式结束当前会话中活动的任何事务,就好像您已经完成了执行语句之前执行COMMIT。网页部分中较低的语句为
LOAD DATA INFILE
。这是我们问题的真正答案:不可能将MySqlBulkLoader
与MySqlTransaction
相关联,至少可以使它按照我们想要的方式运作。然而,如上所述,问题的解决方案可能是检查每个表的主键的索引,锁定表,保存它们的位置,并进行手动"回滚"上传失败后。