sql >> データベース >  >> RDS >> PostgreSQL

Djangoのカーソルは開いているトランザクション内で実行されますか?

    個別の同時トランザクションを取得するには、個別のデータベース接続が必要になると思います。また、djangoはデータベースごとに1つの接続のみを管理していると確信しています。ただし、別のものを作成することもできます。これを行わないのには、いくつかの正当な理由があるかもしれません。複雑さが頭に浮かびます。

    私はこのようなものがうまくいくと思います:

    from django.conf import settings
    from django.db.utils import ConnectionHandler
    
    def my_view(request):
        """Flirt with complexity by using two connections to db"""
        private_connections = ConnectionHandler(settings.DATABASES)
        db = router.db_for_write(model)
        new_conn = private_connections[db]
        new_conn.enter_transaction_management()
        new_conn.managed(True)
        new_cur = new_conn.cursor()
        new_cur.execute("INSERT INTO ...")
        new_conn.commit()
        new_conn.close()
    

    django.db.transactionは使用できないことに注意してください django.db.connectionsのグローバル接続インスタンスで動作するためです 、しかし、いずれにせよ、それは接続オブジェクトのトランザクション管理メソッドの単なる薄いラッパーです。

    本当の質問はなぜこれをしたいのですか?! そして、ラクシュマン・プラサドの答えの何が問題になっていますか?いつでもコミット/ロールバックできるため、単一のビュー内の個別のトランザクションでさまざまなタスクを実行することを妨げるものは何もありません。トランザクションは並列である必要があり、それらの間の論理的な接続を連続して示唆するものではないという事実は、私の考えでは、トランザクションが実際に同じトランザクション内にある必要があることを示しています。

    一方、ある種のオフライン処理をエミュレートしようとしているだけで、その成功または失敗がビューに特に関係しない場合は、メッセージキューを設定し、これらの挿入を個別に実行することを検討してください。処理する。 セロリ それを行うための人気のあるパッケージです。ただし、応答時間が大きな問題ではない場合でも、連続したトランザクションで十分だと思います。

    更新:

    単一の(個別の)トランザクションでビジネスロジックを実行しながら、データベースでバックアップされたキャッシュを自動コミットモードで動作させたい場合は、djangoの方法があります。キャッシュが外部で発生することを確認するだけです。 commit_on_success

    • キャッシングミドルウェアを使用しているだけの場合は、それがTransactionMiddlewareの外部にあることを確認してください 。

    • キャッシュビューデコレータを使用している場合は、TransactionMiddlewareを無効にできると思います。 (または、問題ビューをautocommit内に配置します デコレータ)を使用し、commit_on_successを使用します デコレータ内部 キャッシングデコレータ。面白そうに見えますが、なぜ機能しないのかわかりません:

      @transaction.autocommit
      @cache_page(500)
      @transaction.commit_on_success
      def my_view(request):
          "..."
      
    • テンプレートキャッシュを使用する場合、またはより複雑な手動キャッシュを実行する場合は、TransactionMiddlewareを無効にすることもできます。 (または、問題ビューをautocommit内に配置します デコレータ)を使用し、commit_on_successを使用します コンテキストマネージャーとして、必要なコードのみをマネージドトランザクションに配置し、残りのビューは自動コミットのままにします。

      @transaction.autocommit
      def my_view(request):
          data = cache.get(some_key)
          with transaction.commit_on_success():
              context = do_some_processing(data)
          cache.set(some_key, context['data'])
          return render('template/with/cache/blocks.html', context=context)
      


    1. 列の値がNULLの場合にデフォルト値を達成するにはどうすればよいですか?

    2. テーブル内の属性を同じテーブル内の新しい行内の値に参照するにはどうすればよいですか

    3. MySQLですべての重複を並べて表示

    4. EF 5 with oracle edmx StoreGeneratedPattern=Identityの問題