- PR -

VB2005のマルチスレッド環境でACCESS(mdbファイル)への同時書き込み方法について

投稿者投稿内容
檸檬
ベテラン
会議室デビュー日: 2004/04/26
投稿数: 87
投稿日時: 2007-02-23 13:21
引用:

ひらさんの書き込み (2007-02-23 12:16) より:

デスマの臭いが・・・




まだ工程に遅れはでていませんが、終電モードに突入し余裕がまったくありません;;
しゃっく
会議室デビュー日: 2007/02/23
投稿数: 3
投稿日時: 2007-02-23 14:41
書き込み処理がロックでエラーになるのだから、
排他制御はACCESSがしてくれてますよね。
この処理を最適化したいのでなければ、VB 側で
SQL の実行を排他制御する必要はないと思います。

ロックが原因でエラーになった場合にリトライするのが
最も簡単な対応だと思いますよ。
(CPU を食いつぶさないように Sleep を入れて。)
檸檬
ベテラン
会議室デビュー日: 2004/04/26
投稿数: 87
投稿日時: 2007-02-23 15:16
すいません、解決しました。

いままではそれぞれのスレッドでコネクションをオープンしたまま書き込みを連続して行っていたのですが、これを1回の書き込みのたびにコネクションオープンとクローズを行うようにしたらエラーメッセージもでなくなり、同時書き込みもできるようになりました。

なぜ、これで解決するのか原因はわかりませんが、とりあえずこれで行こうと思います。(後で検証はしっかりしますけど。)

ご助言頂いた方々、どうもありがとうございました。お騒がせしてすいません。

----------
あと余計なお世話ですいませんが、マルチスレッドの排他制御は以下の記事が参考になりましたので上げておきます。
http://www.atmarkit.co.jp/fdotnet/mthread/index/index.html

[ メッセージ編集済み 編集者: あおい 編集日時 2007-02-23 15:33 ]
檸檬
ベテラン
会議室デビュー日: 2004/04/26
投稿数: 87
投稿日時: 2007-02-23 15:27
すいません、しゃっくさんのレスを見る前に解決のレスを入れてしまいました。

ご助言ありがとうございます。

しゃっくさんのおっしゃる通りロックでエラーになったらリトライするのが考え方としてもわかりやすく、一番簡単な方法だと思います。
もし、検証してロックエラーがでるようであればリトライの処理を組み込みたいと思います。




[ メッセージ編集済み 編集者: あおい 編集日時 2007-02-23 15:31 ]
しゃっく
会議室デビュー日: 2007/02/23
投稿数: 3
投稿日時: 2007-02-23 15:51
引用:

いままではそれぞれのスレッドでコネクションをオープンしたまま書き込みを連続して行っていたのですが、これを1回の書き込みのたびにコネクションオープンとクローズを行うようにしたらエラーメッセージもでなくなり、同時書き込みもできるようになりました。


ロックの保持期間が短くなって、競合しにくくなっただけ
ではないでしょうかね・・・^^;

「同時書き込みもできるようになり・・・」というのが、
どのレベルの処理が並行して行えることを確認したのかは、
分かりませんが、十分な評価をオススメします。
るぱん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 1370
投稿日時: 2007-02-23 16:06
るぱんです。

こんなかんじかなぁ?
誰か突っ込んで下さい。
コード:

class ConnectionSingleton{
Connection con = null;
boolean isUsing = false;
String lastUsingClass = "";
//ここは配列にして履歴でも良し。
//でも、リソース食うのでとりあえずこんな感じ

public Connection getConnection(String usingClassName){
コンソール出力(this.lastUsingClass);
this.lastUsingClass = usingClassName;
Connectoin returnCon = null;
if ( !isUsing ){
returnCon = this.con;
}
return returnCon;
}
public void release(){
isUsing = false;
}

private init(){
if (this.con == null) {
this.con = リソースからコネクションを突っ込む;
}
}

/* Singleton処理 */
private ConnectionSingleton(){
init();
}
}


[追記]
工程に関して

本当に作業が全て洗い出せているのかだったり、
見込んでいる作業が見込みどおりかだったり、
終電と言う事とは、なにか見落としがある様な気がします。
[/追記]

[ メッセージ編集済み 編集者: るぱん 編集日時 2007-02-23 16:08 ]
檸檬
ベテラン
会議室デビュー日: 2004/04/26
投稿数: 87
投稿日時: 2007-02-23 16:11
引用:しゃっくさんの書き込みより
-------------------------------------------------------
ロックの保持期間が短くなって、競合しにくくなっただけ
ではないでしょうかね・・・^^;
-------------------------------------------------------

たしかにそんな気がするのですが、2つのスレッドでSleepによるWaitなしでループ文を回して書き込み処理を1万レコード程度連続して行ってもエラーとならなかったため、いまのところはこれでOKということにしました。

再現性がない以上その試験もできないわけでそれに対する処理を組み込むのもどうかと思っています。もし、ロックによるエラーを発生させる方法があればいいのですが。

もちろんあとで検証(と原因究明は時間があれば。。。)をしっかり行いたいと思っています。


[ メッセージ編集済み 編集者: あおい 編集日時 2007-02-23 16:14 ]
しゃっく
会議室デビュー日: 2007/02/23
投稿数: 3
投稿日時: 2007-02-23 16:49
Jet OLEDB Provider では、Command や Recordset 単位で、
ページレベルロック、行レベルロックが制御できるみたいですね。
あと、関係すると思われるとこでは、Connection 単位で、
ファイルのオープンモードとロックディレイ、リトライ回数など
制御できるみたいです。
Connection 単位のは一番最初にオープンした設定が効くのかな・・・

ファイルのロックは常駐ソフト(ウィルススキャン系)や、
人の手(ACCESS で開く)によってもかかります。
(自分とこのプログラムばかり気にして見落としがち)

解決したということですのでご参考程度に。

スキルアップ/キャリアアップ(JOB@IT)