热备份 Java 客户端指南
Red Hat Data Grid 复制链接链接已复制到粘贴板!
数据网格是一个高性能、分布式内存数据存储。
- 无架构数据结构
- 灵活性将不同的对象存储为键值对。
- 基于网格的数据存储
- 设计为在集群间分发和复制数据。
- 弹性扩展
- 动态调整节点数,以在不中断服务的情况下满足需求。
- 数据互操作性
- 在来自不同端点的网格中存储、检索和查询数据。
data Grid 文档 复制链接链接已复制到粘贴板!
有关 Data Grid 的文档可以通过红帽客户门户网站获得。
数据网格下载 复制链接链接已复制到粘贴板!
访问 Data Grid Software Downloads on the Red Hat Customer Portal(Red Hat Customer Portal)。
您必须有一个红帽帐户才能访问和下载数据网格软件。
使开源包含更多 复制链接链接已复制到粘贴板!
红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。我们从这四个术语开始: master、slave、blacklist 和 whitelist。由于此项工作十分艰巨,这些更改将在即将推出的几个发行版本中逐步实施。详情请查看 CTO Chris Wright 的信息。
第 1 章 热备份 Java 客户端 复制链接链接已复制到粘贴板!
通过 Hot Rod Java 客户端 API 远程访问 Data Grid。
1.1. 热环协议 复制链接链接已复制到粘贴板!
热备份是一个二进制 TCP 协议,Data Grid 提供高性能客户端-服务器与以下功能交互:
- 负载平衡。热备份客户端可以使用不同策略在 Data Grid 集群中发送请求。
- 故障转移.热备份客户端可以监控 Data Grid 集群拓扑更改,并自动切换到可用节点。
- 有效的数据位置。热备份客户端可以查找密钥所有者,并直接向那些节点发出请求,从而缩短延迟。
1.2. 客户端 Intelligence 复制链接链接已复制到粘贴板!
热备份客户端使用智能机制高效地向 Data Grid Server 集群发送请求。默认情况下,Hot Rod 协议启用了 HASH_DISTRIBUTION_AWARE 智能机制。
BASIC 智能
客户端没有收到 Data Grid 集群的拓扑更改事件,如加入或离开节点,且只使用您添加到客户端配置中的 Data Grid 服务器网络位置列表。
当 Data Grid Server 没有向 Hot Rod 客户端拓扑发送内部集群拓扑时,启用 BASIC 智能来使用 Hot Rod 客户端配置。
TOPOLOGY_AWARE 智能
客户端接收和存储 Data Grid 集群的拓扑更改事件,以动态跟踪网络上的 Data Grid 服务器。
要接收集群拓扑,客户端需要网络位置(即 IP 地址或主机名),其中至少一个 Hot Rod 服务器在启动时。连接客户端后,Data Grid Server 将拓扑传送到客户端。当 Data Grid Server 节点加入或离开集群时,Data Grid 会将更新的拓扑传送到客户端。
HASH_DISTRIBUTION_AWARE intelligence
除哈希信息外,客户端还接收和存储拓扑更改事件,让客户端能够识别哪些节点存储特定密钥。
例如,考虑一个 put(k,v) 操作。客户端计算键的哈希值,以便它可以找到数据所在内容的确切 Data Grid Server 节点。然后,客户端可以直接连接到那个节点来执行读写操作。
HASH_DISTRIBUTION_AWARE 智能的好处是 Data Grid Server 不需要根据关键散列(使用服务器外资源)查找值。另一个好处是,Data Grid 服务器可以更快地响应客户端请求,因为它们不需要额外的网络往返。
Configuration
ConfigurationBuilder
ConfigurationBuilder builder = new ConfigurationBuilder(); builder.clientIntelligence(ClientIntelligence.BASIC);
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.clientIntelligence(ClientIntelligence.BASIC);
hotrod-client.properties
infinispan.client.hotrod.client_intelligence=BASIC
infinispan.client.hotrod.client_intelligence=BASIC
1.3. 请求平衡 复制链接链接已复制到粘贴板!
热备份 Java 客户端将请求平衡到 Data Grid Server 集群,以便读写操作分散到节点间。
使用 BASIC 或 TOPOLOGY_AWARE 智能的客户端使用所有请求的请求平衡。使用 HASH_DISTRIBUTION_AWARE 智能将请求直接发送到存储所需密钥的节点的客户端。如果节点没有响应,客户端会回退到请求平衡。
默认平衡策略是循环的,因此 Hot Rod 客户端执行请求平衡,例如: s1、s2、s3 是 Data Grid 集群中的节点:
自定义平衡策略
如果您在 Hot Rod 客户端配置中添加类,您可以使用自定义 FailoverRequestBalancingStrategy 实现。
ConfigurationBuilder
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.addServer()
.host("127.0.0.1")
.port(11222)
.balancingStrategy(new MyCustomBalancingStrategy());
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.addServer()
.host("127.0.0.1")
.port(11222)
.balancingStrategy(new MyCustomBalancingStrategy());
hotrod-client.properties
infinispan.client.hotrod.request_balancing_strategy=my.package.MyCustomBalancingStrategy
infinispan.client.hotrod.request_balancing_strategy=my.package.MyCustomBalancingStrategy
1.4. 客户端故障切换 复制链接链接已复制到粘贴板!
当 Data Grid 集群拓扑变化时,热 Rod 客户端可以自动故障转移。例如,是拓扑感知的 Hot Rod 客户端可以检测到一个或多个 Data Grid 服务器何时失败。
除了在集群 Data Grid 服务器间故障转移外,Hot Rod 客户端还可在 Data Grid 集群间故障转移。
例如,您有一个 Data Grid 集群在 New York(NYC)中运行,另一个在伦敦运行的集群(LON)。将请求发送到 NYC 的客户端检测到没有节点可用,因此它们会在 LON 中切换到集群。然后,客户端会维护到 LON 的连接,直到手动切换集群或故障转移为止。
带有故障转移的事务缓存
条件操作,如 putIfAbsent(), replace(), remove() 具有严格的方法返回保障。同样,一些操作可能需要返回以前的值。
尽管 Hot Rod 客户端可以故障转移,但应使用事务缓存来确保操作不部分完成,并在不同的节点上保留冲突的条目。
1.5. 热备份客户端与 Data Grid 服务器兼容 复制链接链接已复制到粘贴板!
Data Grid Server 允许您将 Hot Rod 客户端与不同版本连接。例如,在迁移或升级到您的 Data Grid 集群期间,Hot Rod 客户端版本可能比 Data Grid Server 低。
数据网格建议使用最新的 Hot Rod 客户端版本来受益于最新功能和安全性增强。
data Grid 8 及更新的版本
热环协议版本 3.x 自动协商通过 Data Grid Server 进行客户端的最大版本。
data Grid 7.3 及更早版本
使用比 Data Grid Server 版本高的 Hot Rod 协议版本的客户端必须设置 infinispan.client.hotrod.protocol_version 属性。
第 2 章 配置 Data Grid Maven 存储库 复制链接链接已复制到粘贴板!
数据网格 Java 发行版可通过 Maven 获得。
您可以从客户门户网站下载 Data Grid Maven 存储库,或者从公共 Red Hat Enterprise Maven 存储库拉取 Data Grid 依赖项。
2.1. 下载 Data Grid Maven 存储库 复制链接链接已复制到粘贴板!
如果您不想使用公共 Red Hat Enterprise Maven 软件仓库,将 Data Grid Maven 存储库下载并安装到本地文件系统、Apache HTTP 服务器或 Maven 存储库管理器。
流程
- 登录红帽客户门户。
- 导航到 Data Grid 的 Software Downloads。
- 下载 Red Hat Data Grid 8.3 Maven 存储库。
- 将存档的 Maven 存储库提取到本地文件系统。
-
打开
README.md文件并遵循相应的安装说明。
2.2. 添加 Red Hat Maven 软件仓库 复制链接链接已复制到粘贴板!
在 Maven 构建环境中包括 Red Hat GA 存储库,以获取 Data Grid 工件和依赖项。
流程
将 Red Hat GA 存储库添加到您的 Maven 设置文件,通常通常
~/.m2/settings.xml或直接在项目的pom.xml文件中。Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.3. 配置您的数据网格 POM 复制链接链接已复制到粘贴板!
Maven 使用名为 Project Object Model(POM)文件的配置文件来定义项目并管理构建。POM 文件采用 XML 格式,并描述所生成项目打包和输出的模块和组件依赖关系、构建顺序和目标。
流程
-
打开您的项目
pom.xml进行编辑。 -
使用正确的 Data Grid 版本定义
version.infinispan属性。 在
dependencyManagement部分中包含infinispan-bom。Bill of Materials(BOM)控制依赖关系版本,从而避免了版本冲突,这意味着您不需要为您添加为依赖项的每个 Data Grid 构件设置版本。
-
保存并关闭
pom.xml。
以下示例显示了 Data Grid 版本和 BOM:
后续步骤
根据需要,将 Data Grid 工件作为依赖项添加到您的 pom.xml 中。
第 3 章 热备份 Java 客户端配置 复制链接链接已复制到粘贴板!
Data Grid 提供了一个 Hot Rod Java 客户端配置 API,用于公开配置属性。
3.1. 添加 Hot Rod Java 客户端依赖项 复制链接链接已复制到粘贴板!
添加 Hot Rod Java 客户端依赖项,将其包含在您的项目中。
先决条件
- Java 8 或 Java 11
流程
-
在
pom.xml中添加infinispan-client-hotrod工件作为依赖项,如下所示:
<dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-client-hotrod</artifactId> </dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-client-hotrod</artifactId>
</dependency>
参考
3.2. 配置 Hot Rod 客户端连接 复制链接链接已复制到粘贴板!
配置与 Data Grid Server 的 Hot Rod Java 客户端连接。
流程
-
使用
ConfigurationBuilder类生成不可变配置对象,您可以传递给RemoteCacheManager或在应用程序类路径中使用hotrod-client.properties文件。
ConfigurationBuilder
hotrod-client.properties
infinispan.client.hotrod.server_list = 127.0.0.1:11222,192.0.2.0:11222 infinispan.client.hotrod.auth_username = username infinispan.client.hotrod.auth_password = changeme infinispan.client.hotrod.auth_realm = default infinispan.client.hotrod.sasl_mechanism = SCRAM-SHA-512
infinispan.client.hotrod.server_list = 127.0.0.1:11222,192.0.2.0:11222
infinispan.client.hotrod.auth_username = username
infinispan.client.hotrod.auth_password = changeme
infinispan.client.hotrod.auth_realm = default
infinispan.client.hotrod.sasl_mechanism = SCRAM-SHA-512
配置 Hot Rod URI
您还可以使用 URI 配置 Hot Rod 客户端连接,如下所示:
ConfigurationBuilder
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.uri("hotrod://username:changeme@127.0.0.1:11222,192.0.2.0:11222?auth_realm=default&sasl_mechanism=SCRAM-SHA-512");
RemoteCacheManager cacheManager = new RemoteCacheManager(builder.build());
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.uri("hotrod://username:changeme@127.0.0.1:11222,192.0.2.0:11222?auth_realm=default&sasl_mechanism=SCRAM-SHA-512");
RemoteCacheManager cacheManager = new RemoteCacheManager(builder.build());
hotrod-client.properties
infinispan.client.hotrod.uri = hotrod://username:changeme@127.0.0.1:11222,192.0.2.0:11222?auth_realm=default&sasl_mechanism=SCRAM-SHA-512
infinispan.client.hotrod.uri = hotrod://username:changeme@127.0.0.1:11222,192.0.2.0:11222?auth_realm=default&sasl_mechanism=SCRAM-SHA-512
在类路径外添加属性
如果 hotrod-client.properties 文件不在应用程序类路径上,那么您需要指定位置,如下例所示:
3.2.1. 在客户端配置中定义 Data Grid 集群 复制链接链接已复制到粘贴板!
在 Hot Rod 客户端配置中提供 Data Grid 集群的位置。
流程
至少提供一个 Data Grid 集群名称以及至少有一个节点及
ClusterConfigurationBuilder类的主机名称和端口。如果要将集群定义为默认,以便客户端始终先尝试连接它,然后使用
addServers("<host_name>:<port>; <host_name>:<port>")方法定义服务器列表。
多个集群连接
带有故障转移集群的默认服务器列表
ConfigurationBuilder clientBuilder = new ConfigurationBuilder();
clientBuilder.addServers("hostA1:11222; hostA2:11222")
.addCluster("siteB")
.addClusterNodes("hostB1:11222; hostB2:11223");
RemoteCacheManager remoteCacheManager = new RemoteCacheManager(clientBuilder.build());
ConfigurationBuilder clientBuilder = new ConfigurationBuilder();
clientBuilder.addServers("hostA1:11222; hostA2:11222")
.addCluster("siteB")
.addClusterNodes("hostB1:11222; hostB2:11223");
RemoteCacheManager remoteCacheManager = new RemoteCacheManager(clientBuilder.build());
3.2.2. 手动切换数据网格集群 复制链接链接已复制到粘贴板!
在 Data Grid 集群间手动切换 Hot Rod Java 客户端连接。
流程
在
RemoteCacheManager类中调用以下任一方法:switchToCluster(clusterName)切换到客户端配置中定义的特定集群。switchToDefaultCluster()切换到客户端配置的默认集群,该配置定义为 Data Grid 服务器列表。
3.2.3. 配置连接池 复制链接链接已复制到粘贴板!
热备份 Java 客户端保持与 Data Grid 服务器持久连接的池,以便重复使用 TCP 连接,而不是在每个请求中创建它们。
流程
- 配置 Hot Rod 客户端连接池设置,如下例所示:
ConfigurationBuilder
hotrod-client.properties
3.3. 为 Hot Rod 客户端配置身份验证机制 复制链接链接已复制到粘贴板!
数据网格服务器使用不同的机制来验证 Hot Rod 客户端连接。
流程
-
使用
AuthenticationConfigurationBuilder类中的saslMechanism()方法指定身份验证机制,或使用infinispan.client.hotrod.sasl_mechanism属性。
SCRAM
摘要
PLAIN
OAUTHBEARER
EXTERNAL
GSSAPI
基本回调处理程序
BasicCallbackHandler (如 GSSAPI 示例所示)调用以下回调:
-
NameCallback和PasswordCallback构建客户端主题。 -
在 SASL 身份验证过程中调用
AuthorizeCallback。
带有令牌回调处理程序的 OAUTHBEARER
使用 TokenCallbackHandler 在 OAuth2 令牌过期前刷新 OAuth2 令牌,如下例所示:
Custom CallbackHandler
热备份客户端设置默认 CallbackHandler,将凭据传递给 SASL 机制。在某些情况下,您可能需要提供自定义 回调处理程序,如下例所示:
自定义 回调处理程序 需要处理特定于您使用的验证机制的回调。但是,这超出了本文档的范围,可提供各种可能的回调类型示例。
3.3.1. 创建 GSSAPI 登录上下文 复制链接链接已复制到粘贴板!
要使用 GSSAPI 机制,您必须创建一个 LoginContext,以便 Hot Rod 客户端可以获取 Ticket Granting Ticket(TGT)。
流程
在登录配置文件中定义登录模块。
gss.conf
GssExample { com.sun.security.auth.module.Krb5LoginModule required client=TRUE; };GssExample { com.sun.security.auth.module.Krb5LoginModule required client=TRUE; };Copy to Clipboard Copied! Toggle word wrap Toggle overflow 对于 IBM JDK:
gss-ibm.conf
GssExample { com.ibm.security.auth.module.Krb5LoginModule required client=TRUE; };GssExample { com.ibm.security.auth.module.Krb5LoginModule required client=TRUE; };Copy to Clipboard Copied! Toggle word wrap Toggle overflow 设置以下系统属性:
java.security.auth.login.config=gss.conf java.security.krb5.conf=/etc/krb5.conf
java.security.auth.login.config=gss.conf java.security.krb5.conf=/etc/krb5.confCopy to Clipboard Copied! Toggle word wrap Toggle overflow 注意krb5.conf提供您的 KDC 的位置。使用 kinit 命令通过 Kerberos 进行身份验证并验证krb5.conf。
3.3.2. SASL 验证机制 复制链接链接已复制到粘贴板!
Data Grid Server 使用 Hot Rod 端点支持以下 SASL 验证机制:
| 验证机制 | 描述 | Security realm 类型 | 相关详情 |
|---|---|---|---|
|
|
以纯文本格式使用凭证。您应该只对加密连接使用 | 属性 realm 和 LDAP 域 |
与 |
|
|
使用哈希算法和非ce 值。热 Rod 连接器支持 | 属性 realm 和 LDAP 域 |
与 |
|
|
除了哈希算法和非ce 值外,还使用 salt 值。热 Rod 连接器支持 | 属性 realm 和 LDAP 域 |
与 |
|
|
使用 Kerberos 票据且需要 Kerberos 域控制器。您必须在域配置中添加对应的 | Kerberos realm |
与 |
|
|
使用 Kerberos 票据且需要 Kerberos 域控制器。您必须在域配置中添加对应的 | Kerberos realm |
与 |
|
| 使用客户端证书。 | 信任存储域 |
与 |
|
|
使用 OAuth 令牌,需要 | 令牌域 |
与 |
3.4. 配置 Hot Rod 客户端加密 复制链接链接已复制到粘贴板!
数据网格服务器可以实施 SSL/TLS 加密,并展示带有证书的 Hot Rod 客户端,以建立信任并协商安全连接。
要验证向 Data Grid Server 发布的证书,Hot Rod 客户端需要完整证书链或以 Root CA 开头的部分链。您可以将服务器证书提供给 Hot Rod 客户端,作为信任存储。
或者提供信任存储,您可以使用共享系统证书。
先决条件
- 创建一个信任存储,Hot Rod 客户端可用于验证 Data Grid 服务器身份。
- 如果您配置 Data Grid Server 以验证或验证客户端证书,请根据需要创建一个密钥存储。
流程
-
使用
trustStoreFileName()和trustStorePassword()方法或对应的属性将信任存储添加到客户端配置中。 如果配置客户端证书身份验证,请执行以下操作:
-
使用
keyStoreFileName()和keyStorePassword()方法或对应的属性将密钥存储添加到客户端配置中。 -
配置客户端以使用
EXTERNAL身份验证机制。
-
使用
ConfigurationBuilder
hotrod-client.properties
后续步骤
将客户端信任存储添加到 $RHDG_HOME/server/conf 目录中,并在必要时配置 Data Grid Server 来使用它。
3.5. 启用 Hot Rod 客户端统计信息 复制链接链接已复制到粘贴板!
热备份 Java 客户端可以提供统计数据,其中包括远程缓存和近缓存命中,以及连接池使用量的未命中。
流程
- 打开您的 Hot Rod Java 客户端配置以进行编辑。
-
将
true设置为statistics属性的值,或调用statistics().enable()方法。 -
使用 jmx 和
jmx_domain属性或调用和jmxEnable()jmxDomain()方法,为您的 Hot Rod 客户端导出 JMX MBeans。 - 保存并关闭客户端配置。
热备份 Java 客户端统计
ConfigurationBuilder
hotrod-client.properties
infinispan.client.hotrod.statistics = true infinispan.client.hotrod.jmx = true infinispan.client.hotrod.jmx_domain = my.domain.org
infinispan.client.hotrod.statistics = true
infinispan.client.hotrod.jmx = true
infinispan.client.hotrod.jmx_domain = my.domain.org
3.6. 近缓存 复制链接链接已复制到粘贴板!
接近缓存对 Hot Rod 客户端是本地的,并存储最近使用的数据,因此每个读取操作不需要遍历网络,这会显著提高性能。
接近缓存:
使用 read 操作填充,对
get()或getVersioned()方法的调用。
在以下示例中,put()调用不会填充接近缓存,并且只对条目无效(如果已存在)无效:cache.put("k1", "v1"); cache.get("k1");cache.put("k1", "v1"); cache.get("k1");Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
在 Data Grid Server 上的远程缓存中更新或删除条目时,将客户端监听程序注册为无效条目。
如果条目无效后请求,客户端必须再次从远程缓存中检索这些条目。 - 当客户端切换到不同的服务器时,将被清除。
接近缓存的绑定
您应该始终通过指定可以包含的最大条目数来使用绑定近缓存。当接近缓存达到最大条目数时,驱除会自动发生以删除旧条目。这意味着您不需要手动将缓存大小放在客户端 JVM 的边界内。
不要将最大空闲过期用于接近缓存,因为 near-cache 读取不会传播上次访问时间的条目。
Bloom 过滤器
Bloom 过滤器通过减少失效消息总数来优化写入操作的性能。
Bloom 过滤器:
- 驻留在 Data Grid Server 上,并跟踪客户端所请求的条目。
-
需要每个服务器具有最多活跃连接的连接的连接,并使用
WAIT耗尽的操作。 - 无法用于未绑定近的缓存。
3.6.1. 配置 Near Cache 复制链接链接已复制到粘贴板!
使用近缓存配置 Hot Rod Java 客户端,将最近使用的数据存储在客户端 JVM 中。
流程
- 打开您的 Hot Rod Java 客户端配置。
配置每个缓存,以使用
nearCacheMode(NearCacheMode.INVALIDATED)方法执行近缓存。注意数据网格提供全局近缓存配置属性。但是,这些属性已弃用,您不应该使用它们,而是根据缓存配置近缓存。
-
指定使用
nearCacheMaxEntries()方法驱除前近缓存可以容纳的最大条目数。 -
使用
nearCacheUseBloomFilter()方法启用用于接近缓存的 bloom 过滤器。
3.7. 强制返回值 复制链接链接已复制到粘贴板!
为了避免不必要的数据,在远程缓存中写入操作会返回 null 而不是前面的值。
例如,以下方法调用不会为键返回以前的值:
V remove(Object key); V put(K key, V value);
V remove(Object key);
V put(K key, V value);
但是,您可以更改默认行为,以便调用会返回之前键的值。
流程
- 配置 Hot Rod 客户端,以以下方法之一调用之前键的值:
FORCE_RETURN_VALUE 标记
cache.withFlags(Flag.FORCE_RETURN_VALUE).put("aKey", "newValue")
cache.withFlags(Flag.FORCE_RETURN_VALUE).put("aKey", "newValue")
per-cache
ConfigurationBuilder builder = new ConfigurationBuilder();
// Return previous values for keys for invocations for a specific cache.
builder.remoteCache("mycache")
.forceReturnValues(true);
ConfigurationBuilder builder = new ConfigurationBuilder();
// Return previous values for keys for invocations for a specific cache.
builder.remoteCache("mycache")
.forceReturnValues(true);
hotrod-client.properties
# Use the "*" wildcard in the cache name to return previous values # for all caches that start with the "somecaches" string. infinispan.client.hotrod.cache.somecaches*.force_return_values = true
# Use the "*" wildcard in the cache name to return previous values
# for all caches that start with the "somecaches" string.
infinispan.client.hotrod.cache.somecaches*.force_return_values = true
3.8. 从 Hot Rod 客户端创建远程缓存 复制链接链接已复制到粘贴板!
使用 Data Grid Hot Rod API 从 Java、C++、.NET/C#、JS 客户端等在 Data Grid Server 上创建远程缓存。
此步骤显示如何使用 Hot Rod Java 客户端在首次访问时创建远程缓存。您可以在 Data Grid Tutorials 中找到其他 Hot Rod 客户端的代码示例。
先决条件
-
创建具有
admin权限的 Data Grid 用户。 - 至少一个 Data Grid Server 实例。
- 具有数据网格缓存配置。
流程
-
作为
ConfigurationBuilder的一部分调用remoteCache()方法。 -
在 classpath 上的
hotrod-client.properties文件中设置configuration或configuration_uri属性。
ConfigurationBuilder
hotrod-client.properties
infinispan.client.hotrod.cache.another-cache.configuration=<distributed-cache name=\"another-cache\"/> infinispan.client.hotrod.cache.[my.other.cache].configuration_uri=file:///path/to/infinispan.xml
infinispan.client.hotrod.cache.another-cache.configuration=<distributed-cache name=\"another-cache\"/>
infinispan.client.hotrod.cache.[my.other.cache].configuration_uri=file:///path/to/infinispan.xml
如果您的远程缓存的名称包含 . 字符,那么在使用 hotrod-client.properties 文件时,您必须用方括号括起来。
第 4 章 热备份客户端 API 复制链接链接已复制到粘贴板!
Data Grid Hot Rod 客户端 API 提供了接口,用于远程创建缓存、操作数据、监控集群缓存拓扑等。
4.1. RemoteCache API 复制链接链接已复制到粘贴板!
集合方法 keySet、entrySet 和 值 由远程缓存支持。也就是说,每个方法都会重新调用到 RemoteCache。这很有用,因为它允许检索各种密钥、条目或值,而且如果用户不需要同时存储在客户端内存中。
这些集合遵循了添加和 的 add Allmap 规格,但不支持所有其他方法。
要注意的是,Iterator.remove 和 Set.remove 或 Collection.remove 方法需要超过 1 轮向服务器进行操作。您可以检查 RemoteCache Javadoc,以查看这些文档及其他方法的详情。
迭代器使用情况
这些集合的迭代方法在内部使用 retrieveEntries,如下所述。如果您注意到 检索条目 使用批处理大小的参数。无法向迭代器提供这个方法。因此,在配置 RemoteCacheManager 时,可以通过系统属性 infinispan.client.hotrod.batch_size 或 ConfigurationBuilder 来配置批处理大小。
另外,返回的 retrieveEntries itator 为 Closeable,因为 keySet、entrySet 和 values 中的迭代程序返回 AutoCloseable 变体。因此,当您使用它们时,您应始终关闭这些"迭代"。
try (CloseableIterator<Map.Entry<K, V>> iterator = remoteCache.entrySet().iterator()) {
}
try (CloseableIterator<Map.Entry<K, V>> iterator = remoteCache.entrySet().iterator()) {
}
如果我想要一个深度副本而不是后备集合,会怎么办?
早期版本的 RemoteCache 允许检索 keySet 的深度副本。使用新的后备映射仍有可能,您只需要自行复制内容。您还可以使用 entrySet 和 值 进行此操作,在之前我们不支持它。
Set<K> keysCopy = remoteCache.keySet().stream().collect(Collectors.toSet());
Set<K> keysCopy = remoteCache.keySet().stream().collect(Collectors.toSet());
4.1.1. 不支持的方法 复制链接链接已复制到粘贴板!
Data Grid RemoteCache API 不支持 Cache API 中所有可用的方法,并在调用不支持的方法时抛出 UnsupportedOperationException。
这些方法中的大多数方法不适用于远程缓存(例如,侦听器管理操作),或者对应于本地缓存不支持的方法(例如,包含Value)。
RemoteCache API 不支持从 ConcurrentMap 继承的特定 atomic 操作,例如:
boolean remove(Object key, Object value); boolean replace(Object key, Object value); boolean replace(Object key, Object oldValue, Object value);
boolean remove(Object key, Object value);
boolean replace(Object key, Object value);
boolean replace(Object key, Object oldValue, Object value);
但是,remoteCache 为这些原子操作提供了替代版本的方法,它们通过网络而不是整个值对象发送版本标识符。
4.2. 远程迭代器 API 复制链接链接已复制到粘贴板!
Data Grid 提供了一个远程迭代器 API,用于检索内存资源受限或计划进行服务器端过滤或转换的条目。
4.2.1. 将自定义过滤器部署到数据网格服务器 复制链接链接已复制到粘贴板!
为 Data Grid 服务器实例部署自定义过滤器。
流程
创建可扩展
KeyValueFilterConverterFactory的工厂。Copy to Clipboard Copied! Toggle word wrap Toggle overflow 创建一个 JAR,其中包含
META-INF/services/org.infinispan.filter.KeyValueFilterConverterFactory文件。此文件应包含过滤器工厂类实施的完全限定类名称。如果过滤器使用自定义键/值类,您必须将它们包含在 JAR 文件中,以便过滤器可以正确取消摘要键和/或值实例。
-
将 JAR 文件添加到 Data Grid 服务器安装目录的
server/lib目录中。
4.3. MetadataValue API 复制链接链接已复制到粘贴板!
为版本控制操作使用 MetadataValue 接口。
以下示例显示了只有在条目值没有改变时才会发生删除操作:
4.4. streaming API 复制链接链接已复制到粘贴板!
Data Grid 提供了一个流化 API,它实现返回 InputStream 和 OutputStream 实例的方法,以便您可以在 Hot Rod 客户端和 Data Grid 服务器之间流化大型对象。
考虑以下大型对象示例:
StreamingRemoteCache<String> streamingCache = remoteCache.streaming();
OutputStream os = streamingCache.put("a_large_object");
os.write(...);
os.close();
StreamingRemoteCache<String> streamingCache = remoteCache.streaming();
OutputStream os = streamingCache.put("a_large_object");
os.write(...);
os.close();
您可以按以下方式通过流读取对象:
Streaming API 没有 marshall 值,这意味着您无法同时使用 Streaming 和 Non-Streaming API 访问同一条目。但是,您可以实施自定义 marshaller 来应对这种情况。
RemoteStreamingCache.get(K key) 方法返回的 InputStream 实现了 VersionedMetadata 接口,以便您可以检索版本和过期信息,如下所示:
条件写入方法(putIfAbsent )在值完全发送到服务器后执行实际条件检查。换句话说,在 ()OutputStream 上调用 close() 方法。
4.5. 计数器 API 复制链接链接已复制到粘贴板!
CounterManager 接口是定义、检索和删除计数器的入口点。
热备份客户端可以检索 CounterManager 接口,如下例所示:
// create or obtain your RemoteCacheManager RemoteCacheManager manager = ...; // retrieve the CounterManager CounterManager counterManager = RemoteCounterManagerFactory.asCounterManager(manager);
// create or obtain your RemoteCacheManager
RemoteCacheManager manager = ...;
// retrieve the CounterManager
CounterManager counterManager = RemoteCounterManagerFactory.asCounterManager(manager);
参考
4.6. 创建事件 Listener 复制链接链接已复制到粘贴板!
Java Hot Rod 客户端可以注册监听程序以接收缓存进入级别事件。支持创建、修改和删除的缓存条目。
创建客户端监听程序与嵌入式监听器非常相似,但使用了不同的注释和事件类。以下是打印接收的每个事件的客户端监听程序示例:
ClientCacheEntryCreatedEvent 和 ClientCacheEntryModifiedEvent 实例提供有关受影响密钥和条目版本的信息。此版本可用于调用服务器上的条件操作,如 replaceWithVersion 或 removeWithVersion。
只有在删除操作成功时才会发送 ClientCacheEntryRemovedEvent 事件。换句话说,如果调用 remove 操作但未找到任何条目,则不会生成任何事件。对删除事件的用户(即使没有条目被删除),用户也可以开发事件自定义逻辑来生成这些事件。如需更多信息,请参阅自定义 客户端事件部分。
所有 ClientCacheEntryCreatedEvent、ClientCacheEntryModifiedEvent 和 ClientCacheEntryRemovedEvent 事件实例也都 会提供一个布尔值为CommandRetried() 方法,如果导致这个使用了拓扑更改,则返回 true。这可能是因为此事件已被重复,或另一个事件已被替换(例如: ClientCacheEntryModifiedEvent 替换 ClientCacheEntryCreatedEvent)。
创建客户端侦听器实施后,需要将其注册到服务器。要做到这一点,请执行:
RemoteCache<?, ?> cache = ... cache.addClientListener(new EventPrintListener());
RemoteCache<?, ?> cache = ...
cache.addClientListener(new EventPrintListener());
4.6.1. 删除事件 Listener 复制链接链接已复制到粘贴板!
当不再需要客户端事件监听程序时,可以删除它:
EventPrintListener listener = ... cache.removeClientListener(listener);
EventPrintListener listener = ...
cache.removeClientListener(listener);
4.6.2. 过滤事件 复制链接链接已复制到粘贴板!
为了避免使用事件锁定客户端,用户可以提供过滤功能来限制服务器为特定客户端监听器触发的事件数量。要启用过滤,需要创建一个缓存事件过滤器工厂来生成过滤实例:
以上定义的缓存事件过滤器工厂实例会创建过滤实例,这些实例静态过滤出所有条目,但其键为 1 除外。
要能够使用此缓存事件过滤器注册侦听器,需要为工厂提供唯一名称,Hot Rod 服务器需要插入名称以及缓存事件过滤器实例。
创建包含过滤器实施的 JAR 文件。
如果缓存使用自定义键/值类,这些键/值类必须包含在 JAR 中,以便可以使用正确的未总结键和/或值实例来执行回调。如果客户端监听程序启用了
useRawData,则不需要它,因为回调键/值实例将以二进制格式提供。-
在 JAR 文件中创建
META-INF/services/org.infinispan.notifications.cachelistener.filter.CacheEventFilterFactory文件,并编写过滤器类实施的完全限定类名称。 -
将 JAR 文件添加到 Data Grid 服务器安装目录的
server/lib目录中。 通过将 factory 名称添加到
@ClientListener注释,将客户端监听程序与此缓存事件过滤器连接:@ClientListener(filterFactoryName = "static-filter") public class EventPrintListener { ... }@ClientListener(filterFactoryName = "static-filter") public class EventPrintListener { ... }Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在服务器中注册监听程序:
RemoteCache<?, ?> cache = ... cache.addClientListener(new EventPrintListener());
RemoteCache<?, ?> cache = ... cache.addClientListener(new EventPrintListener());Copy to Clipboard Copied! Toggle word wrap Toggle overflow
您还可以根据执行监听器注册时提供的参数,注册过滤的动态过滤器实例。过滤器使用过滤器工厂接收的参数启用这个选项,例如:
注册监听程序时,会提供执行过滤所需的动态参数:
RemoteCache<?, ?> cache = ...
cache.addClientListener(new EventPrintListener(), new Object[]{1}, null);
RemoteCache<?, ?> cache = ...
cache.addClientListener(new EventPrintListener(), new Object[]{1}, null);
当实例部署到集群中时,过滤实例必须可以被放入集群中,以便可以在事件生成的情况下进行过滤,即使即使是在注册侦听器的不同节点中也会生成事件。要使它们可以被扩展,请扩展 Serializable、Externalizable,或为其提供自定义 外部化 器。
4.6.3. 跳过通知 复制链接链接已复制到粘贴板!
在调用远程 API 方法以不从服务器获取事件通知的情况下,包含 SKIP_LISTENER_ Xmx 标志。例如,要在创建或修改值时防止监听程序通知,请按如下所示设置标记:
remoteCache.withFlags(Flag.SKIP_LISTENER_NOTIFICATION).put(1, "one");
remoteCache.withFlags(Flag.SKIP_LISTENER_NOTIFICATION).put(1, "one");
4.6.4. 自定义事件 复制链接链接已复制到粘贴板!
默认生成的事件仅包含与事件相关的足够信息,但可以避免生成太多的信息,以减少发送它们的成本。(可选)事件中包含的信息可以自定义,使其包含更多信息,如值,或者包含更多的信息。此自定义通过 CacheEventConverter onnectionFactoryy 生成的 CacheEventConvertertal 实例完成:
在上例中,converter 生成一个新的自定义事件,其中包含值以及事件中的键。这会导致大量事件有效负载与默认事件进行比较,但如果与过滤结合使用,它可以降低其网络带宽成本。
转换器的目标类型必须是 Serializable 或 Externalizable。在这种情况下,提供 Externalizer 时,默认将无法使用,因为默认的 Hot Rod 客户端 marshaller 不支持它们。
处理自定义事件需要稍有不同的客户端监听程序实施。要更精确,需要处理 ClientCacheEntryCustomEvent 实例:
ClientCacheEntryCustomEvent 通过 getEventData 方法接收自定义事件,而 getType 方法则提供有关生成了缓存条目创建、修改或删除事件的信息。
与过滤类似,为了能使用此转换器工厂注册侦听器,需要赋予一个唯一名称,并且 Hot Rod 服务器需要用名称插入名称和缓存事件转换程序实例。
创建一个 JAR 文件,其中包含转换器实施。
如果缓存使用自定义键/值类,这些键/值类必须包含在 JAR 中,以便可以使用正确的未总结键和/或值实例来执行回调。如果客户端监听程序启用了
useRawData,则不需要它,因为回调键/值实例将以二进制格式提供。-
在 JAR 文件中创建
META-INF/services/org.infinispan.notifications.cachelistener.filter.CacheEventConverterFactory文件,并编写转换器类实施的完全限定类名称。 -
将 JAR 文件添加到 Data Grid 服务器安装目录的
server/lib目录中。 通过将 factory 名称添加到
@ClientListener注释,将客户端监听程序与此转换器工厂连接:@ClientListener(converterFactoryName = "static-converter") public class CustomEventPrintListener { ... }@ClientListener(converterFactoryName = "static-converter") public class CustomEventPrintListener { ... }Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在服务器中注册监听程序:
RemoteCache<?, ?> cache = ... cache.addClientListener(new CustomEventPrintListener());
RemoteCache<?, ?> cache = ... cache.addClientListener(new CustomEventPrintListener());Copy to Clipboard Copied! Toggle word wrap Toggle overflow
也可以利用动态转换基于监听器提供的参数转换器实例。converters 使用转换器工厂接收的参数启用这个选项。例如:
注册监听器时,会提供进行转换所需的动态参数:
RemoteCache<?, ?> cache = ...
cache.addClientListener(new EventPrintListener(), null, new Object[]{1});
RemoteCache<?, ?> cache = ...
cache.addClientListener(new EventPrintListener(), null, new Object[]{1});
当转换器实例在集群中部署时,必须合并,以便可以正确生成事件,即使事件在注册了监听程序的不同节点中也会发生转换。要使它们可以被扩展,请扩展 Serializable、Externalizable,或为其提供自定义 外部化 器。
4.6.5. 过滤和自定义事件 复制链接链接已复制到粘贴板!
如果要进行事件过滤和自定义,则更容易实现 org.infinispan.notifications.cachelistener.filter.CacheEventFilterConverter,它可让您在单步中进行过滤和自定义。为方便起见,建议直接扩展 org.infinispan.notifications.cachelistener.filter.AbstractCacheEventFilterConverter 而非实施 org.infinispan.notifications.cachelistener.CacheEventFilterConverter。例如:
与过滤器和转换器类似,为了能够使用此组合的过滤器/协调程序注册侦听器,该工厂必须通过 @NamedFactory 注释赋予一个唯一名称,并且 Hot Rod 服务器需要使用名称和缓存事件转换程序实例进行插入。
创建一个 JAR 文件,其中包含转换器实施。
如果缓存使用自定义键/值类,这些键/值类必须包含在 JAR 中,以便可以使用正确的未总结键和/或值实例来执行回调。如果客户端监听程序启用了
useRawData,则不需要它,因为回调键/值实例将以二进制格式提供。-
在 JAR
文件中创建 META-INF/services/org.infinispan.notifications.cachelistener.filter.CacheEventFilterConverteronnectionFactoryy 文件,并编写转换器类实施的完全限定类名称。 -
将 JAR 文件添加到 Data Grid 服务器安装目录的
server/lib目录中。
从客户端的角度来看,为了能够使用组合过滤器和转换器类,客户端监听程序必须定义相同的过滤器工厂和转换器名称,例如:
@ClientListener(filterFactoryName = "dynamic-filter-converter", converterFactoryName = "dynamic-filter-converter")
public class CustomEventPrintListener { ... }
@ClientListener(filterFactoryName = "dynamic-filter-converter", converterFactoryName = "dynamic-filter-converter")
public class CustomEventPrintListener { ... }
当监听器通过过滤器或转换器参数注册时,会提供上例中的动态参数。如果 filter 参数不是空的,则使用那些参数,否则使用转换器参数:
RemoteCache<?, ?> cache = ...
cache.addClientListener(new CustomEventPrintListener(), new Object[]{1}, null);
RemoteCache<?, ?> cache = ...
cache.addClientListener(new CustomEventPrintListener(), new Object[]{1}, null);
4.6.6. event Marshalling 复制链接链接已复制到粘贴板!
热备份服务器可以以不同格式存储数据,但是在这方面,Java Hot Rod 客户端用户仍然可以开发在键入的对象上工作的 CacheEventConverter 或 CacheEventFilter 实例。默认情况下,过滤器和转换器将使用数据作为 POJO(application/x-java-object),但可以通过覆盖 filter/converter 中的方法 format() 覆盖所需的格式。如果格式返回 null,则 filter/converter 将接收数据,因为它存储在其中。
hot Rod Java 客户端可以配置为使用不同的 org.infinispan.commons.marshall.Marshaller 实例。如果这样做并部署 CacheEventConverter 或 CacheEventFilter 实例,若要通过 Java 对象提供过滤器/聚合内容,服务器需要能够转换对象和 marshaller 生成的二进制格式。
要部署 Marshaller 实例服务器端,请按照类似方法来部署 CacheEventConverter 或 CacheEventFilter 实例:
- 创建一个 JAR 文件,其中包含转换器实施。
-
在 JAR 文件中创建
META-INF/services/org.infinispan.commons.marshall.Marshaller文件,并编写 marshaller 类实施的完全限定域名。 -
将 JAR 文件添加到 Data Grid 服务器安装目录的
server/lib目录中。
请注意,Marshaller 可以部署到单独的 jar 中,也可以部署到与 CacheEventConverter 和/or CacheEventFilter 实例相同的 jar 中。
4.6.6.1. 部署 Protostream Marshallers 复制链接链接已复制到粘贴板!
如果缓存存储了 Protobuf 内容,因为当在 Hot Rod 客户端中使用 ProtoStream marshaller 时,不需要部署自定义摘要,因为该格式已经被服务器支持:可以使用 Protobuf 格式将其转换为最常用的格式。
将过滤器/聚合与这些缓存搭配使用时,最好将过滤器/聚合与 Java 对象一起使用,而是对二进制过程的数据一起使用,需要配置额外的 ProtoStream marshallers,以便服务器在过滤/聚合前无法排解数据。要做到这一点,您必须配置所需的 SerializationContextInitializer,作为 Data Grid 服务器配置的一部分。
如需更多信息 ,请参阅缓存编码和 Marshalling。
4.6.7. 侦听器状态处理 复制链接链接已复制到粘贴板!
客户端监听程序注解有一个可选的 includeCurrentState 属性,用于指定在添加监听程序时或当监听器故障转移时,状态将发送到客户端。
默认情况下,includeCurrentState 为 false,但是如果设为 true,并且已在缓存中添加客户端监听程序,服务器会迭代缓存内容,并将每个条目的事件作为 ClientCacheEntryCreated (或者配置了自定义事件)。这使得客户端能够基于现有内容构建一些本地数据结构。迭代内容后,会正常收到事件,因为收到缓存更新。如果集群缓存,则会迭代整个集群范围的内容。
4.6.8. 监听器故障处理 复制链接链接已复制到粘贴板!
当 Hot Rod 客户端注册客户端侦听器时,它能在集群中的单个节点中执行此操作。如果该节点失败,Java Hot Rod 客户端检测到,通过注册到另一节点的所有监听程序来透明地失败。
在这种故障期间,客户端故障转移可能会丢失一些事件。为了避免缺少这些事件,客户端监听程序注解包含名为 includeCurrentState 的可选参数,如果出现故障转移时,缓存内容可以迭代和 ClientCacheEntryCreated 事件(或者配置了自定义事件)。默认情况下,includeCurrentState 设置为 false。
使用回调处理故障切换事件:
@ClientCacheFailover
public void handleFailover(ClientCacheFailoverEvent e) {
...
}
@ClientCacheFailover
public void handleFailover(ClientCacheFailoverEvent e) {
...
}
当客户端缓存了一些数据的情况中,当客户端缓存了一些数据的情况中,在出现问题出现问题时,要考虑到一些事件可能会丢失,它可能会决定在收到失败的事件时清除所有本地缓存的数据,因为知识在事件过后,它将接收整个缓存的内容的事件。
4.7. 热备份 Java 客户端事务 复制链接链接已复制到粘贴板!
您可以在 JTA事务中配置和使用 Hot Rod 客户端。
要参与交易,Hot Rod 客户端需要与它交互的 TransactionManager 以及是否通过 Synchronization 或 XAResource 接口参与事务。
当客户端在准备阶段获取条目的写入锁定时,交易很好。为了避免数据不一致,请务必在事务中 读取有问题的冲突。
4.7.1. 配置服务器 复制链接链接已复制到粘贴板!
服务器中的缓存还必须是客户端参与 JTA事务的事务性。
需要以下服务器配置,否则只进行事务回滚:
-
隔离级别必须是
REPEATABLE_READ。 -
建议使用
PESSIMISTIC锁定模式,但可以使用OPTIMISTIC。 -
事务模式应该是
NON_XA或NON_DURABLE_XA。热环交易不应使用FULL_XA,因为它会降低性能。
例如:
<replicated-cache name="hotrodReplTx"> <locking isolation="REPEATABLE_READ"/> <transaction mode="NON_XA" locking="PESSIMISTIC"/> </replicated-cache>
<replicated-cache name="hotrodReplTx">
<locking isolation="REPEATABLE_READ"/>
<transaction mode="NON_XA" locking="PESSIMISTIC"/>
</replicated-cache>
热 Rod 事务拥有自己的恢复机制。
4.7.2. 配置 Hot Rod 客户端 复制链接链接已复制到粘贴板!
事务性 远程缓存 以每个缓存为基础配置。例外是事务 的超时 (全局),因为单个事务可以与多个 RemoteCache进行交互。
以下示例演示了如何为缓存 my-cache 配置事务远程Cache :
如需配置参数的文档,请参阅 ConfigurationBuilder 和 RemoteCacheConfigurationBuilder Javadoc。
您还可以使用属性文件配置 Java Hot Rod 客户端,如下例所示:
infinispan.client.hotrod.cache.my-cache.transaction.transaction_manager_lookup = org.infinispan.client.hotrod.transaction.lookup.GenericTransactionManagerLookup infinispan.client.hotrod.cache.my-cache.transaction.transaction_mode = NON_XA infinispan.client.hotrod.transaction.timeout = 60000
infinispan.client.hotrod.cache.my-cache.transaction.transaction_manager_lookup = org.infinispan.client.hotrod.transaction.lookup.GenericTransactionManagerLookup
infinispan.client.hotrod.cache.my-cache.transaction.transaction_mode = NON_XA
infinispan.client.hotrod.transaction.timeout = 60000
4.7.2.1. TransactionManagerLookup Interface 复制链接链接已复制到粘贴板!
TransactionManagerLookup 提供了一个入口点,用于获取 事务管理器。
TransactionManagerLookup 可用实现:
- GenericTransactionManagerLookup
- 查找类,用于定位在 Java EE 应用服务器中运行的 TransactionManager。如果无法找到 TransactionManager,则默认为 RemoteTransactionManager。这是 Hot Rod Java 客户端的默认值。
在大多数情况下,GenericTransactionManagerLookup 是合适的。但是,如果您需要集成一个自定义事务管理器,您可以实施 TransactionManager Lookup 接口。
- RemoteTransactionManagerLookup
- 如果没有其他实施,则 basic 和 volatile(易失性) 事务管理器。请注意,这个实现在处理并发事务和恢复时会存在很大的限制。
4.7.3. 事务模式 复制链接链接已复制到粘贴板!
TransactionMode 控制 远程Cache 如何与 TransactionManager 交互。
在 Data Grid 服务器和客户端应用程序中配置事务模式。如果客户端试图在非事务缓存上执行事务操作,则可能会出现运行时例外。
在 Data Grid 配置和客户端设置中,事务模式是相同的。在您的客户端使用以下模式,查看服务器的 Data Grid 配置模式:
NONE- RemoteCache 不与 TransactionManager 交互。这是默认的模式,是非事务性。
NON_XA- RemoteCache 通过 Synchronization 与 TransactionManager 交互。
NON_DURABLE_XA- RemoteCache 通过 XAResource 与 TransactionManager 交互。禁用恢复功能。
FULL_XA-
RemoteCache 通过 XAResource 与 TransactionManager 交互。启用恢复功能。调用
XaResource.recover()方法以检索要恢复的事务。
4.7.4. 使用事务检测冲突 复制链接链接已复制到粘贴板!
事务使用密钥的初始值来检测冲突。
例如,当事务开始时,"k" 的值为"v"。在准备阶段,事务从服务器获取"k"来读取值。如果值已更改,则事务回滚以避免冲突。
事务使用版本来检测变化,而不是检查值相等性。
forceRe returnValue 参数控制 远程Cache 的写操作,有助于避免冲突。它具有以下值:
-
如果为
true,则 TransactionManager 在执行写入操作前从服务器获取最新的值。但是,forceRe returnValue参数仅适用于编写访问第一次密钥的操作。 -
如果为
false,则 TransactionManager 在执行写入操作前不会从服务器获取最新的值。
这个参数不会影响 条件 写入操作,如 replace 或 putIfAbsent,因为它们需要最新的值。
以下事务提供一个示例,其中 forceRe returnValue 参数可以防止有冲突的写操作:
事务 1(TX1)
事务 2(TX2)
在这个示例中,TX1 和 TX2 并行执行。"k"的初始值为 "v"。
-
如果
forceRe returnValue = true,则cache.put()操作会从 TX1 和 TX2 中的服务器获取 "k" 的值。达到锁定的事务,然后是"k"提交。其他事务在提交阶段回滚,因为事务可以检测到"k" 的值不是"v"。 -
如果
forceRe returnValue = false,则cache.put()操作不会从服务器中获取 "k" 的值并返回 null。TX1 和 TX2 都可以成功提交,这会导致冲突。这是因为交易无法检测到"k"的初始值已更改。
以下事务包括 cache.get() 操作以在执行 cache.put() 操作前读取"k"的值:
事务 1(TX1)
事务 2(TX2)
在上述示例中,TX1 和 TX2 都读取密钥,因此 forceRe returnValue 参数不会生效。一个事务提交,另一个回滚。但是,cache.get() 操作需要额外的服务器请求。如果您不需要对服务器请求的效率的 cache.put() 操作返回值。
以下示例演示了如何使用您在 RemoteCacheManager 中配置的 TransactionManager 和 TransactionMode :