选择并更新同一事务中不同数据源中的表

时间:2014-03-06 13:16:25

标签: spring-integration

Spring Integration中<jdbc:inbound-channel-adapter>组件的属性包括data-sourcesqlupdate。这些允许对指定数据库中的表运行单独的SELECT和UPDATE语句。两个sql语句都将成为同一事务的一部分。

此处的限制是SELECT和UPDATE都将针对同一数据源执行。当UPDATE位于不同数据源中的表(而不仅仅是同一服务器上的单独数据库)时,是否存在解决方法?

我们的特定要求是在表中选择在特定时间之前具有时间戳的行。该时间存储在单独数据源的表中。 (它也可以存储在文件中)。如果两个sql语句使用相同的数据库,则<jdbc:inbound-channel-adapter>对于我们开箱即用。在这种情况下,SELECT可以使用表A中存储的时间作为针对表B的查询运行中WHERE子句的一部分。表A中的时间将更新为当前时间,所有这些将是一笔交易的一部分。

我有一个想法是在适配器的sqlupdate属性中使用SpEL来调用bean中的方法。为sql定义的方法将查找存储在文件中的时间,然后返回完整的SELECT语句。为update定义的方法将更新同一文件中的时间并返回空字符串。但是,我不认为这种方法是故障安全的,因为文件的读取和写入不会是数据源使用的同一事务的一部分。

但是,如果保证update仅在提交数据源事务时触发,那么这对我们有用。如果发生故障,数据库事务将提交,但文件不会更新。然后我们会得到重复的行,但应该能够处理它。问题是如果文件已更新且数据库事务失败。这将意味着丢失的消息,我们无法处理。

如果有人对如何处理这种情况有任何见解,我们非常感谢。

1 个答案:

答案 0 :(得分:0)

使用两个不同的通道适配器与pub-sub通道,或出站网关,后跟出站通道适配器。

如有必要,启动两者上游的交易;如果你想要真正的原子性,你需要使用XA事务管理器和XA数据源。或者,您可以通过同步两个事务来接近,以便它们能够非常接近地提交。

请参阅Dave Syer's article "Distributed transactions in Spring, with and without XA",特别是最佳努力1PC部分。