2011-11-26 32 views
1

是否有一个开源的Java库,它将XA支持添加到本地不支持的数据库中?也就是说,它封装了一个非XA JDBC数据源并负责在两阶段提交后面进行必要的提交/回滚操作?将XA与本机不支持的数据库一起使用?

+0

我只使用Oracle和MS SQL Server完成XA,它们都支持事务并提供支持两阶段提交的JDBC驱动程序。 – duffymo

回答

9

不,因为这是不可能的。

让我们回顾一下XA的设计目标。这是一个共识协议,用于保证跨越多个资源管理器的事务的ACID属性。为此,它使用两阶段提交协议:事务管理器准备每个资源管理器,然后提交它们中的每一个。

为使协议正常工作,资源管理器例如数据库,必须在准备阶段做出一定的保证。这些措施包括:a)在提交阶段('Isolation')之前,不对其他进程进行任何更改可视化; b)确保它可以在提交时根据需要执行更新,即使它在准备和提交之间崩溃('Durability')和c)确保在不同交易中操纵的数据具有承诺的一致性属性。实际上唯一的方法就是独占锁定。甚至资源管理者在大多数操作中使用MVCC或其他技术的pgsql和oracle将在准备时使用独占锁。

无法访问db内部,您无法获取锁并通过连接保持它们。因此,您无法编写符合事务要求的代码。因此,XA对数据库引擎的顶部没有分层 - 它必须在烘焙

但是......

您可以将XA行为的假某些方面。根据您的具体应用要求,这可能会制作出有用的解决方案。首先,您可以使用上次资源优化(aka Last Resource Commit Optimization或Last Resource Gambit)将单个非XA即一个阶段资源列入具有一个或多个实际XA资源的XA事务中。通过在处理顺序中排序最后一个阶段资源,您可以在大多数情况下实现类似XA的行为。如果执行过程中的某些点发生崩溃,它会突然崩溃,因此您必须自定义写入数据对帐代码或依靠人员来处理该应急。取决于您的数据的语义,可能或不可能是一个有吸引力的选项。

接下来,您可以实现自定义驱动程序,其操作非常像语义复制。它在准备时将SQL操作的顺序记录到日志中,但直到提交阶段才将它们实际应用于db。这适用于在应用程序级别隔离的事务更新,但如果您依赖数据库为您执行并发控制,则不起作用。例如,您可能会发现提交失败,因为在准备阶段和提交阶段之间发生冲突的更新中有其他内容。你可以使用外部锁管理器,但前提是你的自定义驱动程序是唯一与db通话的。一旦没有意识到该锁管理器的客户出现,所有投注都将关闭。

最后,您可以反转该模型并在XA下使用基于薪酬的交易。在此模型中,您可以在准备时应用更新,并在需要时应用其他操作以在回滚阶段中恢复其效果。这有两个缺点:并发操作可能会读取并操作tx的过早提交的值,这些值随后会回滚,因为准备和提交之间没有隔离;还取决于业务逻辑,生成适当的补偿报表并不容易。即使可以,也需要相当多的复杂管道才能确保即使在碰撞情况下也能正常运行。

实际上,您可能仅限于大多数事务管理器开箱即用的LRCO。其他选项需要大量的交易专业知识才能正确进行,开发/测试开销通常不合理。如果LRCO不会为你工作,坦率地说,重新设计你的应用程序以避免需要XA会更容易。

+0

如果你有一个本地数据库,其工作仅仅是记录哪个阶段(准备,提交等),每个远程数据库都在*和*中,你可以保证所有的客户端都使用你的“事务管理器”访问数据库,这是否工作?这是LRCO提到的吗? – Gili

+0

LRCO =上次资源提交优化,如下所述:http://stackoverflow.com/a/134152/14731 – Gili

+1

>如果您有一个本地数据库,其工作仅用于记录每个远程数据库的哪个阶段(准备,落实等)是在/ umm,为什么你需要本地数据库,现有的tm日志文件将会很好。问题是远程非XA RM从不在准备状态,它可以直接提交或回滚一步。 – Uncredited

相关问题