0

Odoo で 2 つのデータベース間の同期を行っています。リモートで問題がなければ、両側で同期します。ただし、リモートで問題が発生した場合、ローカル データベースの変更はコミットされますが、リモートはコミットされません。つまり、データベースが同期しなくなります。

ローカル データベースに変更を加える方法はありますか。リモート データベースを同期しようとして何か問題が発生した場合は、ローカル データベースを以前の状態にロールバックします。

この方法があります:

@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)

ご覧のとおり、2 つの部分に分かれています。最初にローカル データベースに変更を加え、次にリモートに変更を加えます (ラッパーを使用) xmlrpcliberppeekこのメソッドを 1 つのトランザクションとして作成するにはどうすればよいですか?メソッドの実行中に何か問題が発生した場合、データベースへの変更はロールバックされますか?

4

2 に答える 2

1

これに必要なのは、2 フェーズ コミットです。

一般的な考え方は次のとおりです。

  • ローカルおよびリモートの変更を開始する
  • それぞれに必要な作業を行います
  • リモート側PREPARE TRANSACTIONで、返された ID を永続ストレージに記録します。
  • ローカル側COMMITの変更点
  • 返された ID を持つリモート側COMMIT PREPAREDで、またはローカル コミットが何らかの理由で失敗した場合は、ROLLBACK PREPARED代わりに。

アプリを再起動する場合、準備済みだがコミットされていないリモート トランザクションの記録を確認し、次のことを確認する必要があります。

  • ローカル トランザクションがコミットされた場合) を発行しCOMMIT PREPAREDます。また
  • ローカル トランザクションがコミットされていない場合は、ROLLBACK PREPARED

これを正すのは簡単ではありません。ローカル コミット ID の記録に失敗する単純なアプローチは、実際には何も修正しません。一貫性のないデータベースの状態を、リークされた準備済みトランザクションに置き換えるだけです。準備されたトランザクションの記録を実際に保持し、クラッシュまたは再起動後にそれらを解決する必要があります。ROLLBACK PREPAREDまたはCOMMIT PREPAREDは、接続の問題、DB の再起動などにより失敗する可能性があることに注意してください。

このため、多くの人は、この部分を処理する別のトランザクション マネージャーを使用しています。MSDTC は Windows システムのオプションです。Javaの場合、おそらくJTCを使用できます。C/UNIX システムでは、XA を使用できます。残念ながら、分散型トランザクション マネージャーは、恐ろしくバロック的で不明確な API 設計を引き付けているようです (言えるjavax.transaction.HeuristicMixedExceptionでしょうか?)。

于 2015-01-19T09:31:28.257 に答える
0

2 フェーズ コミットを確認する必要があります。基本的に、これにより、別々のシステムごとに試行コミットを行い、両方が成功した場合にのみ、最終的な「実際の」コミットを行うことができます。

クライアントがクラッシュするなどのケースに対処する必要があります。次に、ぶら下がっているコミットを準備し、それらをロールバックして最初からやり直したいと思うでしょう。

于 2015-01-19T09:29:42.943 に答える