Jag tror att du skulle behöva en separat db-anslutning för att få en separat, samtidig transaktion. Jag är också ganska säker på att django bara hanterar en anslutning per databas. Men du kan skapa en till. Det kan finnas någon bra anledning att inte göra detta. Komplexitet kommer att tänka på.
Jag tror att något sådant här skulle fungera:
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()
Observera att du inte kan använda django.db.transaction
eftersom det fungerar på de globala anslutningsinstanserna i django.db.connections
, men det är i alla fall bara ett tunt omslag runt transaktionshanteringsmetoderna på anslutningsobjektet.
Jag antar att den verkliga frågan är varför vill du göra det här? Och vad är det för fel på Lakshman Prasads svar? Du kan utföra/rulla tillbaka när du vill, så det finns inget som hindrar dig från att utföra olika uppgifter i distinkta transaktioner inom en enda vy. Det faktum att transaktionerna måste vara parallella och inte successiva antyder något logiskt samband mellan dem, vilket enligt mig skulle tyda på att de verkligen borde vara i samma transaktion.
Om du å andra sidan bara försöker efterlikna någon form av offline-bearbetning, vars framgång eller misslyckande inte alls är särskilt relevant för vyn, överväg att ställa in en meddelandekö och utföra dessa infogningar i en separat bearbeta. Selleri är ett populärt paket för att göra just det. Om svarstiden inte är ett stort problem, men jag tror fortfarande att successiva transaktioner borde räcka.
Uppdatering:
Om du vill att din databasstödda cache ska fungera i autocommit-läge medan du fortfarande kör din affärslogik i en enda (separat) transaktion, finns det ett django-sätt. Allt du behöver göra är att se till att cachningen sker utanför commit_on_success
:
-
Om du bara använder cachingmellanvaran, se till att den är utanför
TransactionMiddleware
. -
Om du använder caching-vydekoratörer skulle jag våga gissa att du kan inaktivera
TransactionMiddleware
(eller placera problemvyn i enautocommit
decorator) och användcommit_on_success
dekoratör inuti den cachande dekoratören. Det ser roligt ut, men jag vet inte varför det inte skulle fungera:@transaction.autocommit @cache_page(500) @transaction.commit_on_success def my_view(request): "..."
-
Om du använder mallcachelagring eller gör mer involverad manuell cachelagring kan du också inaktivera
TransactionMiddleware
(eller placera problemvyn i enautocommit
decorator) och användcommit_on_success
som en kontexthanterare för att bara lägga koden du behöver i en hanterad transaktion, och lämna resten av vyn i autocommit.@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)