個別の同時トランザクションを取得するには、個別のデータベース接続が必要になると思います。また、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)