我正在调查异步交易以提高性能。
请您解释一下,在复制的异步缓存中,事务的行为是什么?
如果我有一个由操作组成的事务,其中每个操作都依赖于先前的操作(即操作的执行顺序很重要)。
例如,考虑一个事务T,它执行构建data2所需的data1读取,然后将data2写入缓存。
交易T {
// 1° operation
data1 = get(key1);
// 2° operation
data2 = elaborate(data1);
// 3° operation
put(data2);
}
换句话说,我需要异步执行“整个事务”,但我需要在事务内执行的操作保持同步。
有可能吗?如果是,我如何配置infinispan?
非常感谢
Francesco Sclano
答案 0 :(得分:0)
我猜你已将这些操作包装到tm.begin(); try { ... tm.commit(); } catch (...) { tm.rollback(); }
中。
因此,我假设您使用默认 - 乐观事务和两阶段提交。我还建议启用写入偏斜检查 - 这在Infinispan 7中应该是默认的,但在以前的版本中你必须明确地启用它,并且有些操作在没有它的情况下表现得很奇怪。
对于get
,这始终是同步的 - 您必须等待响应。
在commit
之前,put
基本上只做另一个get
(为了返回值)并记录事务应该在提交期间进行写入。
然后,在提交期间,锁定所有更新条目的 PrepareCommand
是异步发送的 - 因此,您无法知道它是成功还是失败(通常是由于超时,还是由于写入偏斜)检查或更改条件命令中的值。)
第二阶段,覆盖条目和解锁锁的CommitCommand
在此之后同步发送 - 所以你要等到收到响应。但是,如果您有<transaction useSynchronization="true" />
(默认值),即使此命令在某处失败,提交也会成功。
要异步发送CommitCommand
(或RollbackCommand
),您需要配置<transaction syncCommitPhase="false" syncRollbackPhase="false" />
。
我希望我已经正确地解释了这些来源 - 并且不要问我为什么这样做。遗憾的是,我不确定您是否可以配置语义“可靠地提交或回滚此事务,但不报告结果并让我继续”开箱即用。
击>
编辑:异步模式下的提交应为1阶段,因为无论如何都无法检查结果。因此,并发写入可能会在不同节点上重新排序,并且您将使集群不一致,但您不会等待事务完成。
无论如何,如果你想原子地和异步地执行整个块,没有什么比将代码包装到Runnable并在你自己的线程池中执行它更容易了。并使用同步缓存。