0

我正在 Odoo 中的两个数据库之间进行同步。如果它在远程没有任何问题,那么它会在双方同步。但是,如果远程出现问题,则提交本地数据库更改,但远程不会。换句话说,数据库不同步。

有没有办法在本地数据库中进行更改,如果尝试同步远程数据库出现问题,请将本地数据库回滚到以前的状态。

有这个方法:

@api.one
def order_process_now(self):
    servers = self._synchro_before_sale()
    # Process local order
    inv_id = self.action_invoice_create()
    if inv_id:
        inv = self.env['account.invoice'].search([('id', '=', inv_id)])
        inv.signal_workflow('invoice_open')
    for picking in self.picking_ids:
        picking.force_assign()
        picking.action_done()
    # Process remote orders
    self._remote_order_action('order_process_now', servers)

如您所见,它分为两部分。首先它对本地数据库进行更改,然后在远程进行更改(使用xmlrpclib包装erppeek器)。我怎样才能将此方法作为一个事务,所以如果执行方法出现任何问题,对数据库的任何更改都会回滚?

4

2 回答 2

1

你需要的是两阶段提交。

总体思路是:

  • 开始本地和远程更改
  • 对每一个做必要的工作
  • 在远程端PREPARE TRANSACTION并记下持久存储中返回的 ID
  • 在本地方面COMMIT的变化
  • 在返回 ID 的远程端COMMIT PREPARED,或者如果本地提交由于某种原因失败ROLLBACK PREPARED

如果您的应用程序重新启动,它必须查看其准备但未提交的远程事务的记录,并且:

  • 如果本地事务已提交)发出一个COMMIT PREPARED;或者
  • 如果本地事务未提交,则发出ROLLBACK PREPARED

要做到这一点并不容易。无法记录本地提交 ID 的天真的方法并不能真正解决任何问题,它只是用泄露的准备事务替换不一致的数据库状态。实际上,您必须记录准备好的事务并在崩溃或重新启动后解决它们。请记住,ROLLBACK PREPAREDorCOMMIT PREPARED可能由于连接问题、数据库重新启动等而失败。

出于这个原因,许多人使用单独的事务管理器来为他们处理这部分。MSDTC 是 Windows 系统上的一个选项。对于 Java,您应该可以使用 JTC。在 C/UNIX 系统上,您可以使用 XA。不幸的是,分布式事务管理器似乎吸引了可怕的、巴洛克式的和定义不明确的 API 设计(你能说javax.transaction.HeuristicMixedException吗?)

于 2015-01-19T09:31:28.257 回答
0

您需要查看两个阶段提交。基本上,这使您可以在每个单独的系统上进行试用提交,然后只有在两者都成功时才进行最终的“真实”提交。

您仍然需要处理例如客户端崩溃的情况。然后,您将准备好提交,并且您希望将它们回滚并重新开始。

于 2015-01-19T09:29:42.943 回答