首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在本地不支持XA的数据库中使用XA?

在本地不支持XA的数据库中使用XA?
EN

Stack Overflow用户
提问于 2011-11-27 03:25:45
回答 1查看 807关注 0票数 1

有没有开放源码的Java库可以向本地不支持XA的数据库添加XA支持?也就是说,它包装了一个非XA JDBC数据源,并负责两阶段提交的幕后必要的提交/回滚?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-11-29 00:30:56

不,因为这是不可能的。

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

为了使协议正常工作,资源管理器(例如数据库)必须在准备阶段做出某些保证。这包括a)在提交阶段(“隔离”)之前不使任何改变对其他进程可见,b)确保它可以在需要时在提交时执行更新,即使它在准备和提交之间崩溃(“持久性”),以及c)确保在不同事务中操纵的数据表现出所承诺的一致性属性。实际上,实现这一点的唯一方法是独占锁定。即使是在大多数操作中使用MVCC或其他技术的资源管理器,例如pgsql和oracle,也会在准备时使用排它锁。

如果不能访问数据库的内部结构,就不能获取锁并跨连接持有它们。因此,您不能编写能够满足事务需求的代码。因此,没有在数据库引擎之上的XA分层-它必须被烘焙。

然而..。

您可以伪造XA行为的某些方面。根据您确切的应用程序需求,这可能会创建一个有用的解决方案。

首先,您可以使用Last Resource Optimization (也称为Last resource Commit Optimization或Last Resource Gambit)将单个非XA资源(即一个阶段资源)登记到具有一个或多个实际XA资源的XA事务中。通过将单阶段资源按处理顺序排在最后,您可以在大多数场景中实现类似于XA的行为。如果在执行过程中的某些点发生崩溃,它会崩溃得很可怕,因此您必须自定义编写数据协调代码或依靠人工来处理该意外情况。这取决于数据的语义,这可能是一个有吸引力的选择,也可能不是。

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

最后,您可以反转该模型,并在XA下使用基于补偿的事务。在此模型中,您将在准备时应用更新,并在需要时应用其他操作以在回滚阶段逆转其效果。这有两个缺点:并发操作可能会读取和操作稍后回滚的tx的过早提交的值,因为准备和提交之间没有隔离;此外,根据业务逻辑,很难生成合适的补偿语句。即使可以,您也需要相当多的复杂管道,以确保它们即使在崩溃情况下也能正常运行。

实际上,您可能只能使用LRCO,大多数事务管理器都支持LRCO。其他选项需要大量的事务专业知识才能正确执行,而开发/测试开销通常是不合理的。如果LRCO对你不起作用,那么坦率地说,重新设计你的应用程序以避免对XA的需要会更容易。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8280970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档