SQLステートメントをタイムアウトさせる簡単な方法があります(たとえば、空の結果セットやエラーメッセージなどを配信するなど)。そうでなければ、私は仕事のressource予約を失敗させて、別のチャンスを与えることができますか?私はこれまで見落としてきたDBIオプションを探しています。自殺のためにSIGALRMを自分自身に送ることは、私が心に留めていることではなく(私がしなければならないことに頼らざるを得ないかもしれないが)。Perl DBIを使用してOracleの「select for update」をタイムアウトさせるには
コードを擬似化して極端に短くしていますが、ドリフトをキャッチしていただければ幸いです。ここ
my $sql = "SELECT one, two, three FROM sometable WHERE this = ? AND that = ?";
my $sth = $self->make_handle($sql);
eval {
foreach my $this (sort keys %needed_ressources) {
# vvv This is where the idle time is spent vvv
$sth->execute($this, $that) or die("DB connection gone?!");
# ^^^ This is where the idle time is spent ^^^
my ($one, $two, $three) = $sth->fetchrow_array();
unless($one) { # undefined record set == not found
$self->{DB_HANDLE}->rollback();
die("$this not defined for $that!");
}
}
# If we haven't died so far, we can move on
foreach... #similar loop here doing the actual update statement
$self->{DB_HANDLE}->commit();
};
return(1) unless [email protected];
return(undef);
興味のための血みどろの詳細は、次のとおりOracleテーブルを使用して実装さressourceロック機構が存在する大規模並列numbercrunchingを行うアプリケーションにおいて
。各ジョブは、読み取りのためのいくつかのリソースと書き込みのためのいくつかのリソースをロックする必要があり、すべてのロックが正常に取得された場合にのみ起動できます。リソースが解放されるのを辛抱強く待つ代わりに、ジョブはただ失敗し、後でマスタによって再実行される必要があります(これにより、開いているトランザクションの数が少なくなり、パフォーマンスが向上します。
もちろん、実際に表を更新する前に、各行は「SELECT ... FOR UPDATE」文を使用して予約されているため、Oracleは行レベルのロックを使用し、同時トランザクションは表で実行されます。可能な競合状態とデッドロックをさらに減らすために、すべてのジョブは最初に再ソース行を選択し、更新を実行する前に同じ順序を使用して行をロックします。
現在の実装では、これはの場合、ほとんどのケースで問題なく動作します。しかし、Oracleが実際に行ロックを許可するまで、「更新のための選択」ブロックが存在するため、ジョブがそのリソースを待っている間アイドル状態になっている可能性があります。ロッキングのためにちょうど1,2秒待つのはOKですが、10秒以上待ってはいけません。 の場合はのロックが必要ですが、待機する必要がありますので、DB接続全体を設定するとすぐに結果を受け入れることはできません。
は私がいる限り、彼らはM内の場所を指すように私はTFがR ;-))
事前のおかげで多くを持っていなければならないことRTFM答えをいつも感謝しています、
Olfan
「コミットコミット」とはどういう意味ですか? SIGALRMハンドラを設定して、必要な処理を行うことができます。信号だけを避けようとしていますか? – jiggy
私は、マスタープロセスだけがシグナルを処理するように努力しています。たぶんPerlは実際にそれを扱うことができるかもしれませんが、私の内部の脳構造は、父と子の両方のプロセスで異なるシグナルハンドリングを持つ準備ができていません。 – Olfan