SQLite3の使用について

解決


ユッケビビンバ  2015-12-25 01:36:45  No: 47827

はじめまして。
この度ユーザーの所にシステムを導入するに当たり、
SQLite3を利用したサーバー/クライアント型のシステムを制作しようと思っています。
SQLiteはサーバー/クライアント型には向いていないのは分かっているのですが、なんとか上手く運用出来ない物かと考えていますが、
SQLiteを使用するが初めてなもので四苦八苦してます。

そこでまずは可/不可を判定する為にテストPGを作成し、
クラサバ環境で実行してみた所「database is locked」のエラーが発生してしまいます。

環境は
  Delphi XE4
  FireDacにて接続
  SQLite3(3.8.10.2)
  DBはサーバー側に配置し、フォルダに共有

仕様としては
  1.PG起動時にADConnectionにてDBファイルに接続
  2.テーブル(仮にTEST_TBL)をDBGridで表示
  3.行ダブルクリックでレコード情報を画面に表示
  4.確定ボタン押下で書き込み(この時トランザクションBEGIN〜COMMITしてます)

ADConnectionをConnectする際の設定値は

with ADOTEST do
begin
  Open('DriverID=SQLite;'
     + 'Database=\\10.XXX.XXX.XXX\HOYASQL.DB3;'
     + 'AuthMode=Normal;'
     + 'BusyTimeput=100000;'
     + 'SharedCache=False;'
     + 'LockingMode=Normal;'
     + 'Synchronous=Normal;'
     + 'JournalMode=Truncate');
  TxOptions.AutoCommit    := True;
  TxOptions.Isolation     := xiReadCommitted;
  UpdateOptions.LockWait  := True;
  UpdateOptions.LockMode  := lmPessimistic;
  UpdateOptions.LockPoint := lpImmediate;
end;

以下手順の時、
  1.サーバーでPG実行
  2.クライアントでもPG実行
  3.クライアントでDBGridダブルクリック
  4.サーバーでDBGridダブルクリック
  5.サーバー側で確定ボタン押下
    →ここでロックがかかって止まってしまう。
      クライアント側で確定すれば進みます。

上記の現象後は、同処理を行ってもロックがかかりません。

ちなみに
  1.サーバーでPG実行
  2.クライアントでもPG実行
  3.サーバーでDBGridダブルクリック
  4.クライアントでDBGridダブルクリック
  5.クライアント側で確定ボタン押下
    →ここでロックがかかって止まってしまう。
      サーバー側で確定すると「database is locked」が即座に表示されます。

やはりデータベースファイル単位でロックがかかっているから不可なのか、
設定がよろしくないのか、色々調べてみたのですが分かりませんでした。

引き続き私の方でも調査はしてますが、
どなたかご存知の方いらっしゃいましたらご教示願います。


ユッケビビンバ  2015-12-25 02:27:15  No: 47828

記入忘れです。
知りたいのは、何故上記前述の方の確定処理時にロックがかかり、以降はかからなくなるのかが分からないんです。


igy  2015-12-25 08:16:23  No: 47829

> SQLiteはサーバー/クライアント型には向いていないのは分かっているのですが

とのことですが、

FireDAC での SQLite の使用
http://docwiki.embarcadero.com/RADStudio/Seattle/ja/FireDAC_%E3%81%A7%E3%81%AE_SQLite_%E3%81%AE%E4%BD%BF%E7%94%A8
にある
1.5 SQLite に向かない適用方法
http://docwiki.embarcadero.com/RADStudio/Seattle/ja/FireDAC_%E3%81%A7%E3%81%AE_SQLite_%E3%81%AE%E4%BD%BF%E7%94%A8#SQLite_.E3.81.AB.E5.90.91.E3.81.8B.E3.81.AA.E3.81.84.E9.81.A9.E7.94.A8.E6.96.B9.E6.B3.95
からすると、
やはり、SQLite以外のものも検討してみるのは、いかがですか?


ユッケビビンバ  2015-12-29 18:15:32  No: 47830

>>igy様
ご回答ありがとうございます。また返信が遅くなり申し訳ありませんでした。

やはりそうですよね・・・。
私も当サイト他色々と調べてみましたが、同じような事が書かれていました。

他MySQL・PostgressSQLなども候補にはあがったのですが、
現ユーザー環境にインストールを必要とするツールを導入したくはなかったので、ファイルベースのDBをと検討していました。
前提に載せずに申し訳ありませんでした。

Accessも視野に入れてみたのですが、色々と制限(ファイル容量が4GBまで、文字列長が256バイトまでなど)が多く、過去の失敗からAccessも除外していました。
Firebirdなるものもあったのですが、どうやらこれもインストールが必要そうで・・・。

運用面でカバーする方法でなんとか競合を回避していく事になりそうです。

構成としては(1テーブル1DB)
  1.上記グリッドに表示するDB「AAA.DB3」
  2.PG使用中かどうかのDB「BBB.DB3」

非常に初歩的な回避ですが、
1.を誰かが使っている場合は2.に使用中のデータ・フラグを立て、
他の人が使用するとしたら2.のフラグが立っているので使用出来ないようにする。

このやり方だと複数人での実行は出来ないのですが、致し方ないですね。

貴重なご意見ありがとうございました。


DEKO  2016-01-01 08:31:16  No: 47831

> Firebirdなるものもあったのですが、どうやらこれもインストールが必要そうで・・・

Firebird でクライアント側に必要なのは DLL 一つだけです。
サーバ側はインストール (または ZIP 解凍&Install???.bat 実行) が必要ですが。
http://ht-deko.com/delphiforum/?vasthtmlaction=viewtopic&t=1255.0


ユッケビビンバ  2016-01-21 22:29:04  No: 47832

既に解決済みですが、明確な原因が分かりました。

FireDacのオプション設定で
ADConnection.FetchOptions.Modeが関係していて、これの値の初期値が「fmOnDemand」だったのが原因でした。
RowsetSize=50が初期値+「fmOnDemand」の場合、レコード取得が50件毎に取得する状態で、NextRecordが実行されると再度取得に次の50件取得が走るようです。
(RecordCountを調べた時に気づきました)
これを「fmAll」にし、一度のSQLで全件取得出来るようにしただけで、「database is locked」が表示されなくなりました。

複数端末で同時に書き込みを行ったところ、早い方の書き込みが終わるまで遅い方は待ち状態になるので、狙った通りの動きになってくれました。

なぜレコード取得の状態でロックがかかるのかは現在調査中です。


サトウ  2016-02-11 20:07:42  No: 47833

私は、趣味でDBを扱うAPPを作成しています。

当初、SQLiteを使用することも試しましたが、癖が強くやめてしまいました。
今は、Firebirdの組込み版を利用しています。これはDEKOさんも述べているように
DLLを一つ追加するだけで、特にDBのインストールをせずに使えます。

ユーザーは、通常のAPPのインストールをするだけでOKですのでGoodです。
Firebirdを推薦します。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加