假设我们有一个 businessLogic()
方法,它执行两件事:在本地缓存中写入一些信息,并使用 JDBC
将相同信息保存在数据库中,以便缓存和数据库的内容始终相同。
我知道我们可以使用 Spring 的 JDBC
数据源事务管理器在出现异常时自动回滚数据库。但是,在这种情况下,我们如何定义一个自定义事务管理器,同时回滚缓存的内容,从而使缓存和数据库的内容始终保持同步?
谢谢大家。
最佳答案
Gab 的答案是正确的,除了不正确的部分。
XA 确实是协调多个资源更新的标准方法...除了缓存是本地的,即进程内的,它不一定是资源。
缓存并不完全“实现 JTA”,它根据其部署方式在 XA 协议(protocol)中扮演两个角色之一。它可以是 XAResource,但通常仅在其生命周期与客户端进程的生命周期不同时才需要。对于进程内使用,它更可能是同步。
这些角色之间的主要区别是:XAResource 具有容错能力,但 Synchronization 则不然。对于客户端进程内存中的 volatile 缓存,在崩溃后通过查询数据库来重建缓存就足够了。对于进程外的缓存,客户端在 db tx 提交之后但在缓存更新之前崩溃将使缓存不同步,至少在缓存过期或手动刷新之前是这样。
根据缓存实现,无法保证它会自动选择正确的模式。请参阅您选择的实现的配置引用,例如https://infinispan.org/docs/stable/user_guide/user_guide.html#tx_sync_enlist
Spring 实际上也不是 JTA XA 事务管理器,尽管它确实在它们之上提供了一个抽象层。可以使用 Spring 以非 XA 模式驱动数据库,但是您没有用于缓存同步的标准 Hook ,而是需要一个专有接口(interface)。或者,您可以让数据库通过单阶段资源适配器执行伪 XA。对于您的用例来说,完整的 2PC 可能有点过分了。
关于java - 我们可以编写自定义 Spring 事务管理器吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57569834/