現時点ですでに複数のスレッドからParadoxにアクセスしているのですが
突然スレッドが死んでしまったり、アプリ自体が死んでしまうことがあります。
特徴としては、
① 同じTSession、TDatabase、を複数のスレッドから使用しています。
② エイリアスは使用せずにDBフォルダを直接指定しています。
③ TSession の SessionName は明示的に設定しています。
④ TSession は PrivateDir、NetFileDir を指定していません。
⑤ データベースを更新するスレッドでは Transaction を tiDirtyRead に設定
しています。
Delphi7(Pro)+Paradoxの環境です。
同じクラスで異なるオブジェクトなのでしょうか。
同じクラス・同じオブジェクトであれば、アクセスするときにSynchronizedしていますか?
オブジェクトが違うのにそのような現象になるのであれば、DBアクセス部分を1つにして、それをSynchronizedで呼ぶようにしてみてはどうでしょう。
その場合、1つの処理内でDB操作が完結している必要があると思いますので、工夫してください。
TSessionのヘルプによるとスレッド毎に異なるセッションが必要とあります。
アプリケーションの構造は...
スレッドA:SessionA <-> DatabaseA <-> DataSets
スレッドB:SessionB <-> DatabaseB <-> DataSets
(DatabaseAとDatabaseBは同じデータベースを示す。)
という感じになるようです。
ご指摘いただいた Synchronized を使用するとDBアクセス処理がバッチ(どれか一つを処理している間、それ以外の処理が待たされる)状態になるので、反応速度の低下が懸念されると思うのですが、いかがでしょうか。
現在、各スレッドは
① モバイル端末からの受信ファイルの解析、転送
② モバイル端末からの問い合わせ応答
③ PC端末画面からのユーザ操作応答(画面表示、印字)
の機能をを担当しています。
これらの機能は非同期に任意タイミングで発生する可能性があり、また、意図的に優先している機能もありません。少なくとも、②、③の各操作に対する応答時間は1秒以内(特に②)でないとユーザーが納得しない面もあり、厄介な問題です。
今は以下のような感じでコーディングされています。
例)データベースコンポーネント作成部分の抜粋
procedure AThread.AProc ;
begin
// セッション生成
Session1 := TSession.Create(nil);
Session1.SessionName := 'Session1';
Session1.Name := 'Session1';
// データベース生成
Database1 := TDatabase.Create(nil);
Database1.SessionName := m_Session1.SessionName;
Database1.DatabaseName := '.\DB';
Database1.TransIsolation := tiDirtyRead;
Database1.Name := 'Database1' ;
Session1.Databases[0].DatabaseName := Database1.DatabaseName;
// クエリー作成
Query1 := TQuery.Create(nil) ;
Query1.DatabaseName := Database1.DatabaseName;
Query1.SessionName := Session1.SessionName;
end;
ご指摘事項がございましたら、よろしくお願いいたします。
回答ではありませんが、気になった点を幾つか...
セッションやデータベース、データセットを動的に生成されているみたいですが、データモジュールなどに配置できませんか? 大丈夫とは思いますがプログラムで設定していないプロパティの初期値が気になります。
ご存知かもしれませんがParadoxは、標準状態で使うと非常に不安定です。コントロールパネルのBDE AdminでSystem->INITのLOCAL SHAREは、必ずTrueにしておいてください。(<= これ必須です。)
さらにスタンドアローンでもTSessionのNetFileDirとPrivateDirを設定しておいた方が更に安定します。特にPrivateDirは設定しておくことをお勧めします。(でないと運用途中で”ロックファイルが大きすぎます”というエラーが起こることがあります。)
あと、各スレッドで同じテーブルを操作していませんか? あるいは、各スレッドによって同時に同じテーブルに対してデータの書き込みが発生する可能性はないですか? 読み出ししかしない処理では、データセットのReadOnlyを必ずTrueにしておいた方が良いと思います。レコードロックがかかってしまう可能性もあるかもしれません。(<= 推測ですが...)
そもそも、Paradoxでマルチスレッドって大丈夫なのでしょうか?
お世話になっております。
たくさんの丁寧なご回答をいただきましてありがとうございます。
>そもそも、Paradoxでマルチスレッドって大丈夫なのでしょうか?
Paradox でマルチスレッドを稼動させるのは、無理なのでしょうか・・・。
だめだとしたら、現状 Paradox に変わるマルチスレッドに対応できる
新たなデータベースに移行した方がいいのでしょうか。
・・・・ Paradox から移行が簡単なデータベースって何があるんでしょう。
(できれば無償で使用できるものがよいです。)
といってもまだ、あきらめたわけではなく、最悪の時のために確認して
おきたいという意味です。
masayan さんからのご指摘事項を開発陣営に検討させてみます。
ちなみに、LOACL SHARE の値は TRUE に変更させました。
以上、よろしくお願いいたします。
>といってもまだ、あきらめたわけではなく、最悪の時のために確認して
>おきたいという意味です。
スレッドが可能か不可能か、有償か無償、移行が簡単かどうかに関係なく
データベースにどんなモンがあるのと言う意味で、下記を記憶の片隅にどうぞ。
http://kylecordes.com/bag/index.html
>そもそも、Paradoxでマルチスレッドって大丈夫なのでしょうか?
大丈夫です。バリバリ使ってますよ。
皆様、お世話になっております。
私のつたない質問に対して丁寧に回答していただきまして
ありがとうございました。
開発メンバーの方でも解決の糸口が見えてきたそうで、
現状の環境のまま、プログラムの修正を実施する方向で
実際の作業に入りました。
これまで有意なご意見をいただきました、
にしのさん、masayan さん、通りすがりさん、そうせいじさん、
本当にありがとうございました。
これからもよろしくお願いいたします。
ツイート | ![]() |