Java 我们可以编写定制的Spring事务管理器吗?

Java 我们可以编写定制的Spring事务管理器吗?,java,spring,transactions,Java,Spring,Transactions,假设我们有一个businessLogic()方法,它可以做两件事:在本地缓存中写入一些信息,并使用JDBC将相同的信息保存在数据库中,这样缓存和数据库的内容总是相同的 我知道我们可以使用Spring的JDBCDatasource事务管理器在异常情况下自动回滚数据库。但是,在这种情况下,我们如何定义一个自定义事务管理器来回滚缓存的内容,从而使缓存的内容和数据库始终保持同步 谢谢大家。首先,我认为缓存事务管理的任务是多余的。我建议您仅在成功提交数据库级事务时更新缓存 若在数据库中实体的更新和缓存状态

假设我们有一个
businessLogic()
方法,它可以做两件事:在本地缓存中写入一些信息,并使用
JDBC
将相同的信息保存在数据库中,这样缓存和数据库的内容总是相同的

我知道我们可以使用Spring的
JDBC
Datasource事务管理器在异常情况下自动回滚数据库。但是,在这种情况下,我们如何定义一个自定义事务管理器来回滚缓存的内容,从而使缓存的内容和数据库始终保持同步


谢谢大家。

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

若在数据库中实体的更新和缓存状态之间有一个很小的窗口,那个么使用缓存的大多数场景都是完全可以接受的


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

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

然后必须使用xa数据源访问数据库,并使用缓存实现,例如


我对spring boot不是很熟悉,但是事务管理器应该使用适当的配置(无需重写任何内容)管理两个资源之间的事务同步。Gab的答案是正确的,除了不正确的部分

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

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

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

根据缓存实现的不同,不能保证它会自动选择正确的模式。请参阅所选实现的配置参考,例如


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

非常有启发性的回答:)但不太清楚,至少对我来说是这样。可能我们对什么是本地缓存没有相同的概念。Hibernate N2是本地缓存IMHO,但由于它在多个线程之间共享,因此不符合您的定义。关于LLRTO,只有一个资源可以避免2PC,因此缓存或数据库必须是xa。我不知道你最后一句话是怎么说的。您能告诉我我的答案中到底出了什么问题吗?ehcache显然也打算与“spring TransactionManager”一起使用,并针对它进行自动注册: