Вложенные транзакции в Django? - PullRequest
       20

Вложенные транзакции в Django?

1 голос
/ 18 сентября 2009

Допустим, у меня есть модель app1.models.ModelOne, определенная с сохранением, украшенная @commit_on_success. Все исключения, пойманные в ModelOne.save(), создаются заново. Отлично работает на model_one_instance.save().

Однако в app2 мне нужно сделать серию вставок в ModelOne и откатить их все, если какая-либо из них не удалась. Как мне это сделать?

Украшение app2.jobs.do_the_inserts с помощью @commit_on_success не работает должным образом.

Ответы [ 2 ]

4 голосов
/ 18 сентября 2009

Вложенные транзакции зависят от базы данных, поэтому вы потеряете переносимость. Если вам это нужно, я бы подумал об изменении простого @commit_on_save на что-то более гибкое:

def save(commit=True):
  if commit:
    db.start_transaction()
    try:
        self.real_save()
        db.commit_transaction()
    except backend.DatabaseError, e:
        db.rollback_transaction()
        raise e
  else:
    self.real_save()     

В противном случае вы можете запускать произвольные команды SQL, чтобы вы могли вызывать db.connection.cursor().execute() с любыми используемыми вашей базой данных базами, возможно, с проверкой, чтобы ничего не делать для других подсистем, поэтому вы все равно можете использовать sqlite для локального тестирования.

В зависимости от структуры вашего приложения может быть также возможно использование точек сохранения . Я написал несколько утилит, которые делают что-то вроде этого:

  • Начать транзакцию
  • Выполнять обязательные команды
  • Запустить необязательные операторы:
    • Начальная точка сохранения
    • выполнить
    • фиксация или откат точки сохранения
  • Более обязательный SQL
  • 1028 * совершить *
0 голосов
/ 18 сентября 2009

В зависимости от вашего сервера СУБД вложенные транзакции могут вообще не поддерживаться. Правильно реализовать вложенные транзакции в СУБД на самом деле довольно сложно, потому что вам приходится делить блокировки между транзакциями.

Однако то, что вы описываете, не похоже на вложенные транзакции. Я не знаю, поддерживает ли django транзакции XA, но то, что вы описываете, может быть достигнуто с помощью архитектуры монитора TP и СУБД с поддержкой XA (а это большинство из них в наши дни).

Если в вашей платформе нет поддержки транзакций XA, вам придется структурировать транзакции, чтобы где-то хранилась запись о том, как их откатить. Нечто в духе паттерна «Единица работы», описанного в шаблонах корпоративной прикладной архитектуры Фаулера , может послужить хорошим началом для архитектуры такой подсистемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...