JDBC Lock Registry

版本 4.3 引入了 . 某些组件(例如,aggregator 和 resequencer)使用从实例获取的锁来确保一次只有一个线程操作一个组。 在单个组件中执行此功能。 现在,您可以在这些组件上配置外部锁注册表。 与 共享 一起使用时,您可以使用 跨多个应用程序实例提供此功能,以便一次只有一个实例可以操作组。JdbcLockRegistryLockRegistryDefaultLockRegistryMessageGroupStoreJdbcLockRegistryspring-doc.cn

当本地线程释放锁时,另一个本地线程通常可以立即获取该锁。 如果锁由使用其他注册表实例的线程释放,则获取锁可能需要长达 100 毫秒的时间。spring-doc.cn

它基于抽象,它有一个实现。 数据库架构脚本位于包中,该包针对特定的 RDBMS 供应商进行了划分。 例如,下面的清单显示了 lock table 的 H2 DDL:JdbcLockRegistryLockRepositoryDefaultLockRepositoryorg.springframework.integration.jdbcspring-doc.cn

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)
);

可以根据目标数据库设计要求进行更改。 因此,必须在 Bean 定义上使用 property。INT_prefixDefaultLockRepositoryspring-doc.cn

有时,一个应用程序已移动到无法释放分布式锁并删除数据库中的特定记录的状态。 为此,此类死锁可以在下一次锁定调用时由其他应用程序过期。 上的 (TTL) 选项就是为此目的而提供的。 您可能还希望为为给定实例存储的锁指定。 如果是这样,则可以指定 to 与 as a constructor 参数相关联。timeToLiveDefaultLockRepositoryCLIENT_IDDefaultLockRepositoryidDefaultLockRepositoryspring-doc.cn

从版本 5.1.8 开始,可以使用 - a 配置为在锁定记录插入/更新执行之间休眠。 默认情况下,它是毫秒,在某些环境中,非领导者会过于频繁地污染与数据源的连接。JdbcLockRegistryidleBetweenTriesDuration100spring-doc.cn

从版本 5.4 开始,该接口已被引入并添加到 中。 如果锁定的进程比锁的生存时间长,则必须在锁定的进程期间调用该方法。 因此,生存时间可以大大缩短,部署可以快速重新获得丢失的锁。RenewableLockRegistryJdbcLockRegistryrenewLock()spring-doc.cn

仅当锁由当前线程持有时,才能进行锁续订。

从版本 5.5.6 开始,它支持通过 . 有关更多信息,请参阅其 JavaDocs。JdbcLockRegistryJdbcLockRegistry.locksJdbcLockRegistry.setCacheCapacity()spring-doc.cn

从版本 6.0 开始,可以提供 a 而不是依赖于应用程序上下文中的主 bean。DefaultLockRepositoryPlatformTransactionManagerspring-doc.cn

从版本 6.1 开始,可以为 自定义 和 查询 进行配置。 为此,公开了相应的 setter 和 getter。 例如,PostgreSQL 提示的插入查询可以按如下方式配置:DefaultLockRepositoryinsertupdaterenewspring-doc.cn

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

从版本 6.4 开始,该方法返回删除分布式锁的所有权的结果。 如果锁的所有权过期,则该方法会引发。LockRepository.delete()JdbcLockRegistry.JdbcLock.unlock()ConcurrentModificationExceptionspring-doc.cn