2011-07-11 11 views
4

私のperlスクリプトはマルチスレッドであり、各スレッドでは何かをsqlite3データベースに書き込む必要があります。お察しの通り。しかし、私はsqliteのマルチスレッドINSERTの制限

DBD :: SQLiteのの多くを得る::行うDB失敗しました:データベースはscript.plライン264

メッセージでロックされています。私はsqlite3は、マルチスレッドの状況、さらにはINSERTステートメントを処理することができますが、私は多くの場合、同時に8スレッドを挿入すると思うと思います。

大丈夫ですので、このようにはできませんが、データベースがロックされているかどうかを確認するために挿入する前にチェックを実行してから、再びフリーズするまで待ちますか?

「本当の」DBMSに変更したくないのは、単純なスクリプトだからです。

+0

投稿できるコードはどれですか? Perlのマルチスレッドは、他の言語のマルチスレッドと比べて多くの制限があります。あるスレッドからSQLite dbへの更新を取得して別のスレッドが認識できるように、多くのアクロバットを実行する必要があります。 – mob

答えて

6

あなたがデータベースに得ることができるまでブロックする必要がある場合、すなわち、排他的取引をしようと、

$dbh->do("begin exclusive transaction") or die $dbh->errstr; 
#inserts here 
$dbh->do("commit transaction") or die $dbh->errstr; 

こうすることで、あなたがロックを委任Perlで行うのではなく、SQLite。これは、Perl以外のデータベースやスレッドではなく別のPerlプロセスでデータベースを開いていることを除いて、あらゆる理由でより安全です。

@mobがコメントしたように、Perlのスレッドはやや面白い獣です。私はちょうどそれが属しているデータベースによって行わロックを取得したいと思います。

+0

これは私のために働いていません。これを追加した後でも、 "データベースはロックされています"という警告/エラーが表示されます。たとえそれが私が期待していたはずのものであっても、それは私が必要とするものではありません。 :) btw、それは "$ dbh-> do(" commit ")またはdie $ dbh-> errstr;でなければなりません。最後に、そうでなければ構文エラーが出ます。 – Andy

+0

ちょっと待って、ちょうど間違ったやり方をしたと思う。後で戻ってくるだろう。 – Andy

+0

私のせいで泣きました、これは魅力的です。 – Andy

1

1つの選択肢は、独自のステージング表に各スレッドインサートを持ってその変数にlockを使う(ダミー変数で結構です)と、スレッドがロックを持っていながら、最終的なテーブルに挿入することがあるかもしれないありがとう。言い換えれば、何かのような...

sub ThreadStuff 
{ 
    my $tid=threads->tid; 
    #Thread is doing whatever it's doing 
    $dbh->do("delete from staging_" . $tid) or die $dbh->errstr; 
    $dbh->do("insert into staging_" . $tid . "stuff;") or die $dbh->errstr; 

    { 
     lock $hall_pass; 
     $dbh->do("insert into final_table select * from staging_" . $tid) or die $dbh->errstr; 
     #The lock on $hall_pass goes away as soon as we leave this block. 
    } 
    #Other stuff, maybe cleanup or whatever. 
} 
+0

こんにちはジャック、私はコードの説明を求めることがありますか?なぜ私はステージングテーブルが必要ですか?メインテーブルに直接挿入してブロックするのはなぜですか?私が何かを逃したと思うダンプの質問であればSry。 :) – Andy

2

データベースに書き込むとき、SQLiteはデータベースファイル全体をfcntl()でロックします。別のプロセス/スレッドがそれに書き込もうとすると、設定された時間(30秒?)待機してから放棄されます。 SQLiteFAQを参照してください。

ここで、Perlのスレッドは実際にはバグで変わっていますが、それはここで根本的な問題ではありません。私は、SQLiteが最も単純なニーズ以外のものすべてに対して不適切な選択であるという意見になった。

+0

あなたはsqliteについて正しいかもしれませんが、代替案は何ですか?私の目的のためには、本当のRDBMSを使うことが大いにあります。あなたは何を使うのですか? – Andy

+0

残念ながら、少なくとも私が見た限りでは、何もありません。 MySQLは最も近いソリューションです。 – frezik

関連する問題