前提・実現したいこと
C# からスレッドやタスクを利用して、同時に DB(MySQL) からデータの取得を行いたいと考えます。
DB へのアクセスには MySql.Data.MySqlClient.MySqlDataAdapter.Fill() を使用しています。
発生している問題・エラーメッセージ
上記のようなことをすると高い確率で、以下の例外が発生します。
MySql.Data.MySqlClient.MySqlException :
There is already an open DataReader associated with this Connection which must be closed first.
試したこと
例外の原因はひとつのコネクションで同時に複数のアクセスを行ったためと理解しました。
これはそのようなことを行うとデッドロックの発生等を招くこともあり危険であることも理解しました。
現状では .Fill() を行う箇所に各スレッドやタスクで共通のオブジェクトを利用した lock を掛けることによりこのメソッドを同時に実行しないようにしています。
ただ、今回同時アクセスを行うようにしたい箇所は多量の小さなデータの読み込みであり、直列に実行していると時間的にきついところがあります。
まとめて1回のアクセスで読み取れるようにしてもよいのですが、ここまで試した範囲では受け取った後のデータの整理に時間が掛かってしまい、(上記の) lock をつけて並列に実行した方が時間的に有利な状態となっています。
SQL Server では connectionString に MARS を許す設定を加えることで同時アクセスを許可できるようなのですが、MySQL にはそのような機能はないようです。
質問のまとめ
① MySQL でひとつのコネクション内で同時に DB へのアクセスを行う方法があれば教えてください。
② 「発生している問題」に書いた問題が発生するのは、同じコネクション内で複数のアクセスを行えないから。であるならばひとつのアプリケーション内で異なるコネクションを張ることが出来れば解決するように思えます。(根本的な問題の解決になるかは置いておきます)
ひとつのアプリケーション内で、かつ C# で、複数のコネクションを張る方法があれば教えてください。
③ それ以外に、同時にアクセスする方法があるようでしたら教えてください。
よろしくお願いします。
以上です。
以下、追記です。
当該部分のコードは以下のようにしています。
※そのまま書けないので、概要化しています。
C#
1// データを処理する部分 2using( var connection = new MySqlConnection( connection_string ) ) 3{ 4 connection.Open(); 5 6 Parallel.For( 0, 3, id => 7 { 8 while( !<終了条件> ) 9 { 10 // <sql> を用意する 11 // <param> を用意する 12 var res = GetData( connection, <sql>, <param> ); 13 // res をいろいろする 14 } 15 }); 16} 17 18// DB にアクセスする部分 19public DataTable[] GetData( MySqlConnection connection, string sql, Hashtable param ) 20{ 21 var ret = new List<DataTable>(); 22 23 using( var command = new MySqlCommand( sql, connection ) ) 24 { 25 foreach( DictionaryEntry item in <param> ) 26 { 27 coomand.Parameters.Add( new MySqlParameter( item.Key.ToString(), item.Value ?? System.DBNull.Value ) ); 28 } 29 30 using( var adapter = new MySqlDataAdapter( command ) ) 31 { 32 using( var ds = new DataSet() ) 33 { 34 lock( this ) adapter.Fill( ds ); 35 foreach( Data.DataTable item in ds.Tables ) ret.Add( item ); 36 } 37 } 38 } 39 40 return ret.ToArray(); 41}
回答2件
あなたの回答
tips
プレビュー