PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Курсорите в Django работят ли вътре в отворената транзакция?

Вярвам, че ще ви трябва отделна db връзка, за да получите отделна, едновременна транзакция. Също така съм почти сигурен, че django управлява само една връзка на база данни. Но можете да създадете друг. Може да има някаква основателна причина да не правите това. Сложността идва на ум.

Мисля, че нещо подобно ще свърши работа:

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 , но във всеки случай това е само тънка обвивка около методите за управление на транзакциите на обекта за връзка.

Предполагам, че истинският въпрос е защо искате да направите това?! И какво не е наред с отговора на Лакшман Прасад? Можете да ангажирате/връщате назад, когато пожелаете, така че нищо не ви пречи да изпълнявате различни задачи в отделни транзакции в рамките на един изглед. Фактът, че транзакциите трябва да са паралелни, а не последователни, намеква за някаква логическа връзка между тях, което според мен би означавало, че те наистина трябва да са в една и съща транзакция.

Ако, от друга страна, просто се опитвате да емулирате някакъв вид офлайн обработка, успехът или неуспехът на която изобщо не е от особено значение за изгледа, помислете за настройка на опашка от съобщения и извършване на тези вмъквания в отделен процес. Целина е популярен пакет за правене на точно това. Ако обаче времето за отговор не е голямо притеснение, все пак смятам, че последователните транзакции трябва да са достатъчни.

Актуализация:

Ако искате вашият кеш, поддържан от база данни, да работи в режим на автоматично предаване, докато все още изпълнява вашата бизнес логика в една (отделна) транзакция, има 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)
    


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Автоматично връщане назад в postgre с използване на PDO

  2. Как да получите средни стойности за времеви интервали в Postgres

  3. Как да чета данни от PostgreSQL wal файл? Има ли някаква команда за преобразуване на PostgreSQL двоичен формат в четим текстов формат?

  4. Символ с поредица от байтове 0x9d в кодиране „WIN1252“ няма еквивалент в кодиране „UTF8“

  5. Разлика в производителността:условието е поставено в клауза INNER JOIN спрямо WHERE