Jeg tror, du har brug for en separat db-forbindelse for at få en separat, samtidig transaktion. Jeg er også ret sikker på, at django kun administrerer én forbindelse pr. database. Men du kunne lave en anden. Der kan være en god grund til ikke at gøre dette. Kompleksitet kommer til at tænke på.
Jeg tror, at noget som dette ville fungere:
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()
Bemærk, at du ikke kan bruge django.db.transaction
fordi det fungerer på de globale forbindelsesforekomster i django.db.connections
, men under alle omstændigheder er det kun en tynd indpakning omkring transaktionshåndteringsmetoderne på forbindelsesobjektet.
Jeg gætter på, at det egentlige spørgsmål er hvorfor vil du gøre dette?! Og hvad er der galt med Lakshman Prasads svar? Du kan forpligte/rulle tilbage, når du vil, så der er intet, der forhindrer dig i at udføre forskellige opgaver i forskellige transaktioner inden for en enkelt visning. Det faktum, at transaktionerne skal være parallelle og ikke successive, antyder en logisk sammenhæng mellem dem, hvilket efter min mening ville indikere, at de virkelig burde være i samme transaktion.
Hvis du på den anden side bare forsøger at efterligne en form for offline-behandling, hvis succes eller fiasko overhovedet ikke er særlig relevant for visningen, kan du overveje at oprette en beskedkø og udføre disse indsættelser i en separat behandle. Selleri er en populær pakke til netop det. Hvis responstid ikke er et stort problem, mener jeg dog stadig, at successive transaktioner burde være tilstrækkelige.
Opdatering:
Hvis du vil have din databasestøttede cache til at fungere i autocommit-tilstand, mens du stadig kører din forretningslogik i en enkelt (separat) transaktion, er der en django-måde. Alt du skal gøre er at sikre dig, at cachen sker udenfor commit_on_success
:
-
Hvis du kun bruger caching-middlewaren, skal du sørge for, at den er uden for
TransactionMiddleware
. -
Hvis du bruger cachevisningsdekoratorer, vil jeg vove at gætte på, at du kunne deaktivere
TransactionMiddleware
(eller placer problemvisningen i enautocommit
decorator) og brugcommit_on_success
dekoratør indenfor caching-dekoratøren. Det ser sjovt ud, men jeg ved ikke, hvorfor det ikke ville virke:@transaction.autocommit @cache_page(500) @transaction.commit_on_success def my_view(request): "..."
-
Hvis du bruger skabelon-caching eller gør mere involveret manuel caching, kan du også deaktivere
TransactionMiddleware
(eller placer problemvisningen i enautocommit
decorator) og brugcommit_on_success
som kontekstadministrator kun at sætte den kode, du har brug for, i en administreret transaktion, og lade resten af visningen være 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)