JDBC 鎖定註冊表

Version 4.3 引入了 JdbcLockRegistry。某些元件 (例如,聚合器和重新排序器) 使用從 LockRegistry 執行個體取得的鎖定,以確保一次只有一個線程操作群組。DefaultLockRegistry 在單一元件內執行此功能。您現在可以在這些元件上設定外部鎖定註冊表。當與共用 MessageGroupStore 一起使用時,您可以使用 JdbcLockRegistry 在多個應用程式執行個體之間提供此功能,以便一次只有一個執行個體可以操作群組。

當鎖定由本機線程釋放時,另一個本機線程通常可以立即取得鎖定。如果鎖定由使用不同註冊表執行個體的線程釋放,則可能需要最多 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 屬性。

有時,一個應用程式已移動到無法釋放分散式鎖定並移除資料庫中特定記錄的狀態。為此,可以在下一個鎖定調用時由另一個應用程式使此類死鎖過期。DefaultLockRepository 上的 timeToLive (TTL) 選項是為此目的而提供的。您可能還想要為給定 DefaultLockRepository 執行個體儲存的鎖定指定 CLIENT_ID。如果是這樣,您可以指定要與 DefaultLockRepository 關聯的 id 作為建構函式參數。

從 5.1.8 版開始,可以使用 idleBetweenTries (在鎖定記錄插入/更新執行之間休眠的 Duration) 設定 JdbcLockRegistry。預設情況下,它是 100 毫秒,在某些環境中,非領導者過於頻繁地污染與資料來源的連線。

從 5.4 版開始,引入了 RenewableLockRegistry 介面,並將其新增至 JdbcLockRegistry。如果鎖定程序的時間長於鎖定的存活時間,則必須在鎖定程序期間呼叫 renewLock() 方法。因此,可以高度縮短存活時間,並且部署可以快速重新取得遺失的鎖定。

只有當鎖定由當前線程持有時,才能完成鎖定續約。

從 5.5.6 版開始,JdbcLockRegistry 支援透過 JdbcLockRegistry.setCacheCapacity() 自動清除 JdbcLockRegistry.locks 中 JdbcLock 的快取。請參閱其 JavaDocs 以取得更多資訊。

從 6.0 版開始,可以為 DefaultLockRepository 提供 PlatformTransactionManager,而不是依賴應用程式內容中的主要 Bean。

從 6.1 版開始,可以設定 DefaultLockRepository 以進行自訂 insertupdaterenew 查詢。為此,公開了各自的 Setter 和 Getter。例如,可以像這樣設定 PostgreSQL 提示的插入查詢

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