3.7. 热 Rod Java 客户端事务


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

要参与事务,Hot Rod 客户端需要与之交互的 TransactionManager,以及它是否通过同步或 XAResource 接口参与事务。https://docs.oracle.com/javaee/7/api/javax/transaction/Synchronization.html

重要

事务在准备阶段获取条目的写锁是最佳的。为了避免数据不一致,请务必阅读有关 使用 Transactions 的冲突

3.7.1. 配置服务器

服务器中的缓存还必须是事务处理,客户端才会参与 JTA 事务

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

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

例如:

<replicated-cache name="hotrodReplTx">
  <locking isolation="REPEATABLE_READ"/>
  <transaction mode="NON_XA" locking="PESSIMISTIC"/>
</replicated-cache>

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

3.7.2. 配置 Hot Rod 客户端

事务的 RemoteCache 会根据缓存进行配置。例外是事务的超时,它是全局的,因为单个事务可以与多个 RemoteCaches 交互。

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

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

有关配置参数的文档,请参阅配置 Builder 和 RemoteCache ConfigurationBuilder 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

3.7.2.1. TransactionManagerLookup Interface

TransactionManagerLookup 提供了一个入口点,用于获取 TransactionManager

TransactionManagerLookup 的可用实现:

GenericTransactionManagerLookup
查找类,用于查找在 Java EE 应用服务器中运行的 TransactionManager。如果无法找到 TransactionManager,则默认为 RemoteTransactionManager。这是 Hot Rod Java 客户端的默认设置。
提示

在大多数情况下,GenericTransactionManagerLookup 是合适的。但是,如果您需要集成自定义 TransactionManagerLookup 接口,您可以实现 TransactionManager Lookup 接口。

RemoteTransactionManagerLookup
如果没有其他实施,则基本和易失性 TransactionManager。请注意,这个实现在处理并发事务和恢复时有很大的限制。

3.7.3. 事务模式

TransactionMode 控制 RemoteCache 如何与 TransactionManager 交互。

重要

在 Data Grid 服务器和您的客户端应用程序上配置事务模式。如果客户端试图对非事务缓存执行事务操作,则可能会出现运行时异常。

在 Data Grid 配置和客户端设置中,事务模式都相同。将以下模式与客户端搭配使用,请参阅服务器的 Data Grid 配置模式:

NONE
RemoteCache 不与 TransactionManager 交互。这是默认模式,不是事务处理模式。
NON_XA
RemoteCache 通过 同步TransactionManager 交互。
NON_DURABLE_XA
RemoteCache 通过 XAResourceTransactionManager 交互。恢复功能被禁用。
FULL_XA
RemoteCache 通过 XAResourceTransactionManager 交互。启用恢复功能。调用 XaResource.recover () 方法,以检索要恢复的事务。

3.7.4. 使用事务检测冲突

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

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

注意

事务使用版本来检测更改,而不是检查值相等。

forceReturnValue 参数控制 RemoteCache 的写入操作,并帮助避免冲突。它有以下值:

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

此参数不会影响 替换 或放置 if Absent条件 写入操作,因为它们需要最新的值。

以下事务提供了一个示例,其中 forceReturnValue 参数可以防止出现冲突的写入操作:

事务 1 (TX1)

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

tm.begin();
cache.put("k", "v1");
tm.commit();

事务 2 (TX2)

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

tm.begin();
cache.put("k", "v2");
tm.commit();

在这个示例中,TX1 和 TX2 并行执行。"k"的初始值为 "v"。

  • 如果 forceReturnValue = true,则 cache.put () 操作从 TX1 和 TX2 的服务器获取"k"的值。首先获取"k"锁定的事务,然后提交。其他事务会在提交阶段回滚,因为事务可以检测到 "k" 的值为 "v"。
  • 如果 forceReturnValue = 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();

事务 2 (TX2)

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

tm.begin();
cache.get("k");
cache.put("k", "v2");
tm.commit();

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

3.7.5. 使用 Configured Transaction Manager 和 Transaction Mode

以下示例演示了如何使用在 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();
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.