此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Integration 6.5.1spring-doc.cadn.net.cn

JDBC 锁注册表

4.3 版引入了JdbcLockRegistry. 某些组件(例如,聚合器和重排序器)使用从LockRegistry实例,以确保一次只有一个线程作一个组。 这DefaultLockRegistry在单个组件中执行此功能。您现在可以在这些组件上配置外部锁注册表。与共享的MessageGroupStore,您可以使用JdbcLockRegistry跨多个应用程序实例提供此功能,以便一次只有一个实例可以作该组。spring-doc.cadn.net.cn

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

JdbcLockRegistry基于LockRepository抽象,它有一个DefaultLockRepository实现。 数据库架构脚本位于org.springframework.integration.jdbcpackage,它针对特定的 RDBMS 提供商进行划分。例如,以下列表显示了锁表的 H2 DDL:spring-doc.cadn.net.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)
);

INT_可以根据目标数据库的设计要求进行更改。因此,您必须使用prefix属性DefaultLockRepositorybean 定义。spring-doc.cadn.net.cn

有时,一个应用程序已进入无法释放分布式锁并删除数据库中的特定记录的状态。为此,此类死锁可能会在下一次锁定调用时由另一个应用程序过期。 这timeToLive(TTL) 选项DefaultLockRepository为此目的而提供。您可能还想指定CLIENT_ID对于为给定存储的锁DefaultLockRepository实例。 如果是这样,您可以指定idDefaultLockRepository作为构造函数参数。spring-doc.cadn.net.cn

从 5.1.8 版开始,JdbcLockRegistry可以使用idleBetweenTries-一个Duration在锁定记录插入/更新执行之间休眠。默认情况下,它是100毫秒级,并且在某些环境中,非领导者过于频繁地污染与数据源的连接。spring-doc.cadn.net.cn

从 5.4 版本开始,RenewableLockRegistry接口已被引入并添加到JdbcLockRegistry. 这renewLock()方法必须在锁定进程期间调用,以防锁定进程将比锁的生存时间长。因此,生存时间可以大大缩短,并且部署可以快速重新获取丢失的锁。spring-doc.cadn.net.cn

仅当锁由当前线程持有时,才能完成锁更新。

从 5.5.6 版本开始,JdbcLockRegistry支持自动清理缓存 JdbcLock inJdbcLockRegistry.locks通过JdbcLockRegistry.setCacheCapacity(). 有关更多信息,请参阅其 Javadocs。spring-doc.cadn.net.cn

从 6.0 版开始,DefaultLockRepository可以提供PlatformTransactionManager而不是依赖应用程序上下文中的主 Bean。spring-doc.cadn.net.cn

从 6.1 版开始,DefaultLockRepository可配置为自定义insert,updaterenew查询。 为此,公开了相应的 setter 和 getter。例如,PostgreSQL 提示的插入查询可以配置如下:spring-doc.cadn.net.cn

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

从 6.4 版开始,LockRepository.delete()方法返回删除分布式锁所有权的结果。和JdbcLockRegistry.JdbcLock.unlock()方法 抛出ConcurrentModificationException如果锁的所有权已过期。spring-doc.cadn.net.cn

从 7.0 版开始,JdbcLock实现DistributedLock接口,支持自定义锁定状态数据的生存时间(TTL)功能。 一个JdbcLock现在可以使用lock(Duration ttl)tryLock(long time, TimeUnit unit, Duration ttl)方法,具有指定的生存时间 (TTL) 值。 这JdbcLockRegistry现在提供新的renewLock(Object lockKey, Duration ttl)方法,允许您使用自定义生存时间值续订锁。所有生存时间的默认生存时间JdbcLock实例存储在相同的JdbcLockRegistry现在可以由新构造函数设置JdbcLockRegistry(LockRepository client, Duration expireAfter). 的 APILockRepositoryDefaultLockRepository也进行了修改以支持该功能。spring-doc.cadn.net.cn

如果您已经在使用早期版本的JdbcLockRegistryDefaultLockRepository,请执行必要的 DDL 来修改INT_LOCK表,然后升级到此版本。spring-doc.cadn.net.cn

以下是用于将新列添加到锁表的 Postgres DDL 示例:spring-doc.cadn.net.cn

ALTER TABLE INT_LOCK ADD EXPIRED_AFTER TIMESTAMP NOT NULL;