4.7. 热备份 Java 客户端事务


您可以在 JTA事务中配置和使用 Hot Rod 客户端。

要参与交易,Hot Rod 客户端需要与它交互的 TransactionManager 以及是否通过 SynchronizationXAResource 接口参与事务。

重要

当客户端在准备阶段获取条目的写入锁定时,交易很好。为了避免数据不一致,请务必在事务中 读取有问题的冲突

4.7.1. 配置服务器

服务器中的缓存还必须是客户端参与 JTA事务的事务性。

需要以下服务器配置,否则只进行事务回滚:

  • 隔离级别必须是 REPEATABLE_READ
  • 建议使用 PESSIMISTIC 锁定模式,但可以使用 OPTIMISTIC
  • 事务模式应该是 NON_XANON_DURABLE_XA。热环交易不应使用 FULL_XA,因为它会降低性能。

例如:

<replicated-cache name="hotrodReplTx">
  <locking isolation="REPEATABLE_READ"/>
  <transaction mode="NON_XA" locking="PESSIMISTIC"/>
</replicated-cache>
Copy to Clipboard Toggle word wrap

热 Rod 事务拥有自己的恢复机制。

4.7.2. 配置 Hot Rod 客户端

事务性 远程缓存 以每个缓存为基础配置。例外是事务 的超时 (全局),因为单个事务可以与多个 RemoteCache进行交互。

以下示例演示了如何为缓存 my-cache 配置事务远程Cache

org.infinispan.client.hotrod.configuration.ConfigurationBuilder cb = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder();
//other client configuration parameters
cb.transactionTimeout(1, TimeUnit.MINUTES);
cb.remoteCache("my-cache")
   .transactionManagerLookup(GenericTransactionManagerLookup.getInstance())
   .transactionMode(TransactionMode.NON_XA);
Copy to Clipboard Toggle word wrap

如需配置参数的文档,请参阅 ConfigurationBuilderRemoteCacheConfigurationBuilder 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
Copy to Clipboard Toggle word wrap

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 通过 SynchronizationTransactionManager 交互。
NON_DURABLE_XA
RemoteCache 通过 XAResourceTransactionManager 交互。禁用恢复功能。
FULL_XA
RemoteCache 通过 XAResourceTransactionManager 交互。启用恢复功能。调用 XaResource.recover() 方法以检索要恢复的事务。

4.7.4. 使用事务检测冲突

事务使用密钥的初始值来检测冲突。

例如,当事务开始时,"k" 的值为"v"。在准备阶段,事务从服务器获取"k"来读取值。如果值已更改,则事务回滚以避免冲突。

注意

事务使用版本来检测变化,而不是检查值相等性。

forceRe returnValue 参数控制 远程Cache 的写操作,有助于避免冲突。它具有以下值:

  • 如果为 true,则 TransactionManager 在执行写入操作前从服务器获取最新的值。但是,forceRe returnValue 参数仅适用于编写访问第一次密钥的操作。
  • 如果为 false,则 TransactionManager 在执行写入操作前不会从服务器获取最新的值。
注意

这个参数不会影响 条件 写入操作,如 replaceputIfAbsent,因为它们需要最新的值。

以下事务提供一个示例,其中 forceRe returnValue 参数可以防止有冲突的写操作:

事务 1(TX1)

RemoteCache<String, String> cache = ...
TransactionManager tm = ...

tm.begin();
cache.put("k", "v1");
tm.commit();
Copy to Clipboard Toggle word wrap

事务 2(TX2)

RemoteCache<String, String> cache = ...
TransactionManager tm = ...

tm.begin();
cache.put("k", "v2");
tm.commit();
Copy to Clipboard Toggle word wrap

在这个示例中,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)

RemoteCache<String, String> cache = ...
TransactionManager tm = ...

tm.begin();
cache.get("k");
cache.put("k", "v1");
tm.commit();
Copy to Clipboard Toggle word wrap

事务 2(TX2)

RemoteCache<String, String> cache = ...
TransactionManager tm = ...

tm.begin();
cache.get("k");
cache.put("k", "v2");
tm.commit();
Copy to Clipboard Toggle word wrap

在上述示例中,TX1 和 TX2 都读取密钥,因此 forceRe returnValue 参数不会生效。一个事务提交,另一个回滚。但是,cache.get() 操作需要额外的服务器请求。如果您不需要对服务器请求的效率的 cache.put() 操作返回值。

以下示例演示了如何使用您在 RemoteCacheManager 中配置的 TransactionManagerTransactionMode

//Configure the transaction manager and transaction mode.
org.infinispan.client.hotrod.configuration.ConfigurationBuilder cb = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder();
cb.remoteCache("my-cache")
    .transactionManagerLookup(RemoteTransactionManagerLookup.getInstance())
    .transactionMode(TransactionMode.NON_XA);

RemoteCacheManager rcm = new RemoteCacheManager(cb.build());

//The my-cache instance uses the RemoteCacheManager configuration.
RemoteCache<String, String> cache = rcm.getCache("my-cache");

//Return the transaction manager that the cache uses.
TransactionManager tm = cache.getTransactionManager();

//Perform a simple transaction.
tm.begin();
cache.put("k1", "v1");
System.out.println("K1 value is " + cache.get("k1"));
tm.commit();
Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat