2017-01-26 6 views
2

Djangoバージョン1.10.5 with Postgres 9.6.1複数DBトランザクション

私は昨年、マルチスキーマのデフォルトデータベース環境で作業していました。しかし、私は1つのデータベースを3つのデータベースに分割することに決めました。

私はすべての3つのデータベースのマスター/スレーブルータで作業しています。

私は 'デフォルト'のデータベースキーを使用していません。代わりに、私は 'db1'、 'db2'、および 'db3'を持っています

私が混乱している部分は、このマルチデータベース環境でのトランザクションです。

この例では、期待どおりに失敗します。当然私には明らかである@transaction.atomic(using='db1')を使用しないことによって引き起こされた。

@transaction.atomic() 
def edit(self, context): 
    """Edit 

    :param dict context: Context 

    :return: None 
    """ 

    # Check if employee exists 
    try: 
     result = Passport.objects.get(pk=self.user.employee_id) 
    except Passport.DoesNotExist: 
     return False 

    result.name = context.get('name') 

    result.save() 

私は理解しようとしているという理由だけで、この奇妙な例を持っている...しかし、私はこれが失敗すると予想しているだろうが、それはしません。

@transaction.atomic(using='db1') 
def edit(self, context): 
    """Edit 

    :param dict context: Context 

    :return: None 
    """ 

    # Check if employee exists 
    try: 
     result = Passport.objects.get(pk=self.user.employee_id) 
    except Passport.DoesNotExist: 
     return False 

    result.name = context.get('name') 

    with transaction.atomic(using='db2'): 
     result.save() 

存在しないPassportモデルDB2モデルではまったく同じです。

ルーターはすべての書き込みがそれぞれの尊重されたDBに行くように設定されています。

したがって、アトミックトランザクションでusing='db1'を設定する目的は何ですか。私はソースを見て、 "使用していない"ときにはデフォルトはdefaultになっています。

上記の例では、最初のトランザクションの内部で別のトランザクションを作成しましたが、今度はモデルが存在しないusing='db2'です。私はそれが失敗したと考えましたが、データが適切なデータベースに書き込まれませんでした。

3つのデータベースすべてとやり取りする必要があり、3つのデータベースすべてに書き込むときに1つの問題が発生した場合、3つすべてをロールバックする必要があります。もちろんコミットした。

おそらく誰かが私を理解するためにこれを打ち砕くのを助けることができますか?

+2

エクササイズ全体は、postgresqlが大量のデータを処理できないという誤った前提に基づいているようです。できる。そしてそれは他のどのオープンソースデータベースよりもはるかに優れています – e4c5

+0

実際、私はマスター/スレーブ環境でのレプリケーションのためにこれらを分割しています。 3つのデータベースのうちの2つを全く複製する必要はありません。将来の緊張を取り除くために、私はマルチスキーマからマルチdbに分割しました – Diemuzi

+0

合理的な音ですが、まだ努力する価値があるのだろうかと思います。あなたのマスタースレーブが遠くない限り、不要なものを複製するコスト(お金と計算)はごくわずかです。 – e4c5

答えて

1

は、と解釈されています.X内のトランザクションの中で、次のデータベースコマンドを実行してください。

実際には、はデータベースXでトランザクションを開き、それをコミットするかブロックの末尾にロールバックする

あるいは、documentationはそれを置くよう:ボンネットの下に

を、Djangoのトランザクション管理コード:一番外側のアトミックブロックに入るとき

  • は、トランザクションを開きます。
  • は、最も外側のブロックを終了するときにトランザクションをコミットまたはロールバックします。

与えられたコマンドのために使用するデータベースの質問は、あなたのrouter、ないusing句によって決定されます。だからあなたのtransaction.atomic(using='db2')ブロックは無意味です(単にdb2でトランザクションを開いて閉じます)が、エラーではありません。

+0

故障のためにありがとう。多かれ少なかれ、私は単に状況を過度に考えていました。非常に多くの文書を読んだ後でさえ、決して100%クリアされませんでしたが、これは助けになり、私が探していたものです。 – Diemuzi

関連する問題