JDBC 鎖登錄檔
版本 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 開始,JdbcLockRegistry 可以配置 idleBetweenTries —— 一個 Duration,用於在鎖記錄插入/更新執行之間休眠。預設情況下,它是 100 毫秒,在某些環境中,非領導者會過於頻繁地用資料來源汙染連線。
從版本 5.4 開始,引入了 RenewableLockRegistry 介面並將其新增到 JdbcLockRegistry。如果在鎖定過程比鎖的存活時間長的情況下,必須在鎖定過程中呼叫 renewLock() 方法。這樣可以大大減少存活時間,並且部署可以快速重新獲取丟失的鎖。
| 只有當前執行緒持有鎖才能續訂鎖。 |
從版本 5.5.6 開始,JdbcLockRegistry 透過 JdbcLockRegistry.setCacheCapacity() 支援自動清理 JdbcLockRegistry.locks 中的 JdbcLock 快取。有關更多資訊,請參閱其 Javadocs。
從版本 6.0 開始,DefaultLockRepository 可以提供 PlatformTransactionManager,而不是依賴應用程式上下文中的主 bean。
從版本 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。
從版本 7.0 開始,JdbcLock 實現了 DistributedLock 介面,以支援鎖狀態資料的自定義存活時間 (TTL) 功能。現在可以使用 lock(Duration ttl) 或 tryLock(long time, TimeUnit unit, Duration ttl) 方法獲取 JdbcLock,並指定一個存活時間 (TTL) 值。JdbcLockRegistry 現在提供了新的 renewLock(Object lockKey, Duration ttl) 方法,允許您使用自定義存活時間值續訂鎖。儲存在同一 JdbcLockRegistry 中的所有 JdbcLock 例項的預設存活時間現在可以透過新的建構函式 JdbcLockRegistry(LockRepository client, Duration expireAfter) 設定。LockRepository 和 DefaultLockRepository 的 API 也已修改以支援此功能。
|
如果您已經在使用早期版本的 以下是 Postgres DDL 的示例,用於向鎖表新增新列
|