複数のプロセスがテーブルに挿入し、単一のプロセスがそこから選択するデータベース シナリオ (私は Oracle を使用しています) があります。テーブルは基本的に中間ストレージとして使用され、複数のプロセス (以下ではライターと呼ばれます) がログ イベントを書き込み、そこから単一のプロセス (以下ではリーダーと呼ばれます) がさらに処理するためにイベントを読み取ります。リーダーは、テーブルに挿入されたすべてのイベントを読み取る必要があります。
現在、これは、挿入された各レコードに昇順の ID が割り当てられることによって行われます。リーダーは、以前に読み取ったブロックの最大 ID よりも ID が大きいエントリのブロックをテーブルから定期的に選択します。例:
SELECT
*
FROM
TRANSACTION_LOG
WHERE
id > (
SELECT
last_id
FROM
READER_STATUS
);
このアプローチの問題は、ライターが同時に動作するため、行が昇順で割り当てられている場合でも、割り当てられた ID に従って行が常に順番に挿入されるとは限らないことです。つまり、id=100 の行は、id=110 のレコードの後に書き込まれることがあります。これは、id=110 の行を書き込むプロセスが、レコード id=100 を書き込むプロセスの後に開始されたが、最初にコミットされたためです。これにより、リーダーが id=110 の行を既に読み取った場合、id=100 の行が失われる可能性があります。
ライターにテーブルの排他ロックを強制すると、ライターが順次挿入し、リーダーが未処理のコミットを待機するようになるため、問題が解決します。ただし、これはおそらくそれほど高速ではありません。
私の考えでは、Reader は、未解決の Writer コミットを待ってから読み取るだけで十分です。つまり、すべてのライターが終了するまで、リーダーが読み取りを行っている限り、ライターは同時に動作し続ける可能性があります。
私の質問は次のとおり
です。ライター プロセスの未処理のコミットを待機するようにリーダー プロセスに指示するにはどうすればよいですか? 上記の問題に対する代替案も歓迎します。