別の同時トランザクションを取得するには、別のデータベース接続が必要になると思います。また、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
。
本当の問題は、なぜこれをやりたいのかということだと思います! そして、ラクシュマン・プラサドの答えのどこが間違っているのでしょうか? いつでもコミット/ロールバックできるため、単一のビュー内の異なるトランザクションで異なるタスクを実行することを妨げるものは何もありません。トランザクションが並列でなければならず、連続してはならないという事実は、それらの間の何らかの論理的なつながりを暗示しています。私の考えでは、トランザクションが実際には同じトランザクションにある必要があることを示しています。
一方、なんらかのオフライン処理をエミュレートしようとしているだけで、その成功または失敗がビューに特に関係しない場合は、メッセージ キューを設定し、これらの挿入を個別に実行することを検討してください。処理する。 Celeryはまさにそれを行うための人気のあるパッケージです。ただし、応答時間が大きな問題ではない場合でも、連続したトランザクションで十分だと思います。
アップデート:
ビジネス ロジックを 1 つの (個別の) トランザクションで実行しながら、データベースにバックアップされたキャッシュを自動コミット モードで動作させたい場合は、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)