- PR -

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

投稿者投稿内容
檸檬
ベテラン
会議室デビュー日: 2004/04/26
投稿数: 87
投稿日時: 2007-02-23 09:48
こんにちわ。お世話になっております。
いまVB2005で作った1つのプログラムの中で開始した2つのスレッドから同時にACCESSの1テーブルへ書き込みを行おうとしています。ところが、たまに以下のエラーメッセージが出力され書き込みに失敗してしまいます。

エラーメッセージ
-------------------------------
現在ロックされているので、更新できませんでした。
-------------------------------

VBからACCESSへの書き込みには、「OleDbConnection」と「OleDbCommand」を使い「OleDbCommand」の「ExecuteNonQuery」によりINSERT文を発行して行っております。

実行環境は以下の通りです。
OS:WindowsServer2003SP1
言語:VB2005Professional(SPなし)
DB:ACCESS2003SP2

※開発期間的にSQLServerに乗り換えることはできないため、ACCESSでなんとかしないといけません。
※検索しやすいようにキーワードを入れておきます。「排他制御」「ロック」

参考になることはなんでもご意見をお待ちしております。宜しくお願い致します。

[ メッセージ編集済み 編集者: あおい 編集日時 2007-02-23 09:51 ]
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2007-02-23 10:38
引用:

あおいさんの書き込み (2007-02-23 09:48) より:
こんにちわ。お世話になっております。
いまVB2005で作った1つのプログラムの中で開始した2つのスレッドから同時にACCESSの1テーブルへ書き込みを行おうとしています。ところが、たまに以下のエラーメッセージが出力され書き込みに失敗してしまいます。


念のために確認しておくけど、OleDbConnectionとOleDbCommandのインスタンスはそれぞれのスレッド用に2つづつ用意しているんですよね?OleDbConnectionやOleDbCommandのメンバはスレッドセーフではありませんから、同じインスタンスのメンバを複数のスレッドから呼び出していたら動きませんよ。
檸檬
ベテラン
会議室デビュー日: 2004/04/26
投稿数: 87
投稿日時: 2007-02-23 10:51
引用
----------
念のために確認しておくけど、OleDbConnectionとOleDbCommandのインスタンスはそれぞれのスレッド用に2つづつ用意しているんですよね?OleDbConnectionやOleDbCommandのメンバはスレッドセーフではありませんから、同じインスタンスのメンバを複数のスレッドから呼び出していたら動きませんよ。
----------

DBへの書き込み処理をクラス化してOleDbConnectionとOleDbCommandもカプセル化しています。そして、それぞれのスレッドで書き込み用のクラスをインスタンス化して使用しているので、それぞれのスレッド用にインスタンスを用意できていると考えています。



[ メッセージ編集済み 編集者: あおい 編集日時 2007-02-23 10:54 ]
めだか
大ベテラン
会議室デビュー日: 2004/11/11
投稿数: 109
投稿日時: 2007-02-23 11:12
自前で論理ロック実装して、トランザクションにするしかないのでは?

http://www.naboki.net/access/achell/achell_01.html
るぱん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 1370
投稿日時: 2007-02-23 11:25
るぱんです。

インスタンス化してるのなら、
Singletonにするとか、待ち行列にするとかじゃぁ駄目?
檸檬
ベテラン
会議室デビュー日: 2004/04/26
投稿数: 87
投稿日時: 2007-02-23 11:29
引用:

めだかさんの書き込み (2007-02-23 11:12) より:
自前で論理ロック実装して、トランザクションにするしかないのでは?

http://www.naboki.net/access/achell/achell_01.html



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

リスクがあっても行レベルロック(か他に簡単にできる方法)で書き込んでしまいたい思っていました。(リスクはDBの最適化やバックアップ等で軽減されるかなと、あと耐久試験でも確認しますけど。)

自前での排他制御の方法として、DBへの書き込み処理をプログラムのメインスレッドに行わせる方法を考えていますが、もっと良い方法かスレッドのままで排他制御できる方法がありましたらアドバイス頂きたいです。宜しくお願い致します。
ひら
ぬし
会議室デビュー日: 2005/03/04
投稿数: 260
投稿日時: 2007-02-23 12:16
引用:

あおいさんの書き込み (2007-02-23 09:48) より:
※開発期間的にSQLServerに乗り換えることはできないため、ACCESSでなんとかしないといけません。


デスマの臭いが・・・
檸檬
ベテラン
会議室デビュー日: 2004/04/26
投稿数: 87
投稿日時: 2007-02-23 13:20
引用:

るぱんさんの書き込み (2007-02-23 11:25) より:

インスタンス化してるのなら、
Singletonにするとか、待ち行列にするとかじゃぁ駄目?



るぱんさん、ご助言ありがとうございます。

Singletonというのは使ったことがないのでよくわからないのですが、唯一のインスタンスにするということであれば、甕星さんのおっしゃっていた「OleDbConnectionやOleDbCommandのメンバはスレッドセーフではない」にひっかかるような気がするのですが。

待ち行列にするというのは、1から待ち行列を実装するということでしょうか。待ち行列を(簡単に)実装するためのクラスがVBに用意されていたりするのでしょうか?

できれば一番簡単な方法で排他制御を実装したいと考えております。
よろしくお願いします。

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