JDBC ロックレジストリ

バージョン 4.3 は JdbcLockRegistry を導入しました。特定のコンポーネント(アグリゲーターやリシーケンサーなど)は、LockRegistry インスタンスから取得したロックを使用して、一度に 1 つのスレッドのみがグループを操作するようにします。DefaultLockRegistry は、単一のコンポーネント内でこの機能を実行します。これらのコンポーネントで外部ロックレジストリを構成できるようになりました。共有 MessageGroupStore で使用する場合、JdbcLockRegistry を使用して複数のアプリケーションインスタンスにこの機能を提供し、一度に 1 つのインスタンスのみがグループを操作できます。

ローカルスレッドによってロックが解除されると、通常、別のローカルスレッドがすぐにロックを取得できます。別のレジストリインスタンスを使用するスレッドによってロックが解放された場合、ロックを取得するのに最大 100 ミリ秒かかることがあります。

JdbcLockRegistry は LockRepository 抽象化に基づいており、DefaultLockRepository 実装があります。データベーススキーマスクリプトは org.springframework.integration.jdbc パッケージにあり、特定の RDBMS ベンダー用に分割されています。例: 次のリストは、ロックテーブルの H2 DDL を示しています。

CREATE TABLE INT_LOCK  (
    LOCK_KEY CHAR(36),
    REGION VARCHAR(100),
    CLIENT_ID CHAR(36),
    CREATED_DATE TIMESTAMP NOT NULL,
    constraint INT_LOCK_PK primary key (LOCK_KEY, REGION)
);

INT_ は、ターゲットデータベースの設計要件に応じて変更できます。DefaultLockRepository Bean 定義で prefix プロパティを使用する必要があります。

場合によっては、1 つのアプリケーションが、分散ロックを解放してデータベース内の特定のレコードを削除できない状態に移行することがあります。この目的のために、そのようなデッドロックは、次回のロック呼び出し時に他のアプリケーションによって期限切れになります。DefaultLockRepository の timeToLive (TTL) オプションは、この目的のために提供されています。特定の DefaultLockRepository インスタンスに保存されるロックに CLIENT_ID を指定することもできます。その場合は、コンストラクターパラメーターとして DefaultLockRepository に関連付けられる id を指定できます。

バージョン 5.1.8 から、JdbcLockRegistry は idleBetweenTries (ロックレコードの挿入 / 更新の実行間でスリープする Duration ) で構成できます。デフォルトでは、100 ミリ秒であり、一部の環境では、非リーダーがデータソースとの接続を頻繁に汚染します。

バージョン 5.4 以降、RenewableLockRegistry インターフェースが導入され、JdbcLockRegistry に追加されました。ロックされたプロセスがロックの存続時間よりも長くなる場合は、ロックされたプロセス中に renewLock() メソッドを呼び出す必要があります。そのため、存続時間を大幅に短縮でき、デプロイは失われたロックをすばやく取り戻すことができます。

ロックの更新は、ロックが現在のスレッドによって保持されている場合にのみ実行できます。

バージョン 5.5.6 以降、JdbcLockRegistry は、JdbcLockRegistry.setCacheCapacity() を介した JdbcLockRegistry.locks 内の JdbcLock のキャッシュの自動クリーンアップをサポートします。詳細については、JavaDocs を参照してください。

バージョン 6.0 以降では、アプリケーションコンテキストからのプライマリ Bean に依存する代わりに、DefaultLockRepository に PlatformTransactionManager を提供できるようになりました。

バージョン 6.1 以降、DefaultLockRepository はカスタム insertupdaterenew クエリ用に構成できます。この目的のために、それぞれの setter と getter が公開されます。例: PostgreSQL ヒントの挿入クエリは次のように構成できます。

lockRepository.setInsertQuery(lockRepository.getInsertQuery() + " ON CONFLICT DO NOTHING");