gpt4 book ai didi

java - 将 XA 与本身不支持它的数据库一起使用?

转载 作者:行者123 更新时间:2023-11-29 09:56:53 25 4
gpt4 key购买 nike

是否有开源 Java 库可以为本身不支持 XA 的数据库添加 XA 支持?也就是说,它包装了一个非 XA JDBC 数据源并在幕后为两阶段提交处理必要的提交/回滚?

最佳答案

不,因为这是不可能的。

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

为了使协议(protocol)正常运行,资源管理器(例如数据库,必须在准备阶段做出一定的保证。这些包括 a) 在提交阶段之前不让任何更改对其他进程可见('隔离'),b) 确保它可以在需要时在提交时执行更新,即使它在准备和提交之间崩溃('持久性')和c) 确保在不同交易中操作的数据表现出 promise 的一致性属性。实际上,实现它的唯一方法是独占锁定。甚至资源管理器,例如在大多数操作期间使用 MVCC 或其他技术的 pgsql 和 oracle 将在准备时获取独占锁。

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

然而...

您可以伪造 XA 行为的某些方面。根据您的具体应用要求,这可能有助于制定有用的解决方案。

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

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

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

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

关于java - 将 XA 与本身不支持它的数据库一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8280970/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com