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
はカスタム insert
、update
、renew
クエリ用に構成できます。この目的のために、それぞれの setter と getter が公開されます。例: PostgreSQL ヒントの挿入クエリは次のように構成できます。
lockRepository.setInsertQuery(lockRepository.getInsertQuery() + " ON CONFLICT DO NOTHING");
バージョン 6.4 以降、LockRepository.delete()
メソッドは分散ロックの所有権を削除した結果を返します。また、JdbcLockRegistry.JdbcLock.unlock()
メソッドは、ロックの所有権が期限切れの場合に ConcurrentModificationException
をスローします。