为了账号安全,请及时绑定邮箱和手机立即绑定

我们可以编写自定义 Spring 事务管理器吗?

我们可以编写自定义 Spring 事务管理器吗?

心有法竹 2023-06-14 15:58:03
假设我们有一个businessLogic()方法做两件事:在本地缓存中写入一些信息并将相同的信息保存在使用的数据库中,JDBC以便缓存和数据库的内容始终相同。我知道我们可以使用 Spring 的JDBC数据源事务管理器在出现异常时自动回滚数据库。但是,在这种情况下,我们如何定义一个自定义的事务管理器,它也回滚缓存的内容,以便缓存和 DB 的内容始终保持同步?谢谢大家。
查看完整描述

3 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

Gab 的回答是正确的,除了不正确的部分。

XA 确实是协调多个资源更新的标准方法...除了缓存是本地的,即进程内缓存,它不一定是资源。

缓存并不完全“实现 JTA”,它根据其部署方式充当 XA 协议中的两个角色之一。它可以是 XAResource,但通常只有在其生命周期不同于客户端进程的情况下才需要。对于进程内使用,它更有可能是同步。

这些角色之间的主要区别在于:XAResource 是容错的,但 Synchronization 不是。对于客户端进程内存中的易失性缓存,在崩溃后通过查询数据库重建缓存就足够了。对于进程外的缓存,客户端在 db tx 提交之后但在缓存更新之前崩溃将使缓存不同步,至少直到它过期或被手动刷新。

根据缓存实现,不能保证它会自动选择正确的模式。

Spring 实际上也不是 JTA XA 事务管理器,尽管它确实在它们之上提供了一个抽象层。可以使用 Spring 在非 XA 模式下驱动数据库,但是你没有用于缓存同步的标准挂钩,你需要一个专有接口。或者您可以让数据库通过单阶段资源适配器执行伪 XA。Full-on 2PC 对于您的用例来说可能有点矫枉过正。


查看完整回答
反对 回复 2023-06-14
?
Qyouu

TA贡献1786条经验 获得超11个赞

首先我认为缓存的事务管理任务是多余的。我建议您仅在成功提交数据库级事务后才更新缓存。

如果数据库中实体的更新与其缓存状态之间的窗口很小,那么大多数使用缓存的场景都是完全可以接受的。

如果您的案例拒绝任何缓存过时的可能性,那么您可能必须避免使用缓存或使用一些特殊的缓存,可能是与支持事务的原始数据相同的数据库。否则,您在尝试保持两个不同系统之间的一致性时遇到问题:数据库级别和缓存级别。大多数时候,你能达到的最好结果是最终一致性——这意味着无论如何你都会有不一致状态的窗口,只有到那时(最终)数据才会变得一致。


查看完整回答
反对 回复 2023-06-14
?
UYOU

TA贡献1878条经验 获得超4个赞

处理分布在多个资源之间的事务的标准方法是使用XA

然后,您必须使用 xa-datasource 访问您的数据库并使用实现JTA 的缓存实现,例如。缓存。

我对 spring boot 不是很熟悉,但是事务管理器应该通过适当的配置(不需要重写任何东西)开箱即用地管理跨两个资源的事务同步


查看完整回答
反对 回复 2023-06-14
  • 3 回答
  • 0 关注
  • 112 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信