sql >> Databáze >  >> RDS >> PostgreSQL

Běží kurzory v Django uvnitř otevřené transakce?

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 do autocommit dekoratér) a použijte commit_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 do autocommit dekoratér) a použijte commit_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)
    


  1. Omezení pouze pro jeden záznam označený jako výchozí

  2. Vlastnost objektu PHP obsahuje závorky

  3. Potřebuje vaše firma HR databázi?

  4. mysql změnit všechny hodnoty ve sloupci