Věřím, že byste potřebovali samostatné připojení db, abyste získali samostatnou, současnou transakci. Jsem si také docela jistý, že django spravuje pouze jedno připojení na databázi. Ale můžete vytvořit další. Může existovat dobrý důvod, proč to neudělat. Napadá mě složitost.
Myslím, že něco takového by fungovalo:
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()
Pamatujte, že nemůžete použít django.db.transaction
protože funguje na globálních instancích připojení v django.db.connections
, ale v každém případě je to jen tenký obal kolem metod správy transakcí na objektu připojení.
Myslím, že skutečná otázka je proč to chcete udělat?! A co je špatného na odpovědi Lakshmana Prasada? Můžete potvrdit/vrátit zpět, kdykoli chcete, takže vám nic nebrání v provádění různých úkolů v různých transakcích v rámci jednoho pohledu. Skutečnost, že transakce musí být paralelní a ne po sobě jdoucí, naznačuje nějakou logickou souvislost mezi nimi, což by podle mého názoru naznačovalo, že by skutečně měly být ve stejné transakci.
Pokud se na druhou stranu jen snažíte napodobit nějaký druh offline zpracování, jehož úspěch nebo neúspěch není pro daný pohled nijak zvlášť relevantní, zvažte vytvoření fronty zpráv a provádění těchto vložení v samostatném proces. Celer je oblíbený balíček právě pro to. Pokud však doba odezvy není hlavním problémem, stále si myslím, že po sobě jdoucí transakce by měly stačit.
Aktualizace:
Pokud chcete, aby vaše mezipaměť zálohovaná databází fungovala v režimu autocommit a přitom stále běžela vaše obchodní logika v jedné (samostatné) transakci, existuje způsob django. Jediné, co musíte udělat, je ujistit se, že ukládání do mezipaměti probíhá venku commit_on_success
:
-
Pokud pouze používáte mezipaměťový middleware, ujistěte se, že je mimo
TransactionMiddleware
. -
Pokud používáte dekorátory zobrazení mezipaměti, odvážil bych se odhadnout, že byste mohli zakázat
TransactionMiddleware
(nebo vložte zobrazení problému doautocommit
dekoratér) a použijtecommit_on_success
dekoratér uvnitř dekoratér ukládání do mezipaměti. Vypadá to legračně, ale nevím, proč by to nefungovalo:@transaction.autocommit @cache_page(500) @transaction.commit_on_success def my_view(request): "..."
-
Pokud používáte ukládání do mezipaměti šablon nebo provádíte složitější ruční ukládání do mezipaměti, můžete také zakázat
TransactionMiddleware
(nebo vložte zobrazení problému doautocommit
dekoratér) a použijtecommit_on_success
jako kontextový manažer umístíte do spravované transakce pouze kód, který potřebujete, a zbytek zobrazení ponechá v automatickém potvrzení.@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)