orokusaki
orokusaki

Reputation: 57198

Django - Inception style transaction handling

I'm no transaction / database expert, so pardon my ignorance in the wording here:

When you use Django's transaction.commit_on_success(func), any error that's propagated to the control of commit_on_success will roll back the transaction which is really helpful of course in case you need some all-or-nothing action in a method, etc. This makes Django's view-based transaction handling great for views that do a lot of stuff.

Sometimes I wrap model methods or plain old helper functions in commit_on_success to achieve the same all-or-nothing behavior.

The problem comes when you have nested Django transactions. Example: A transaction protected view calls a model method that's wrapped in commit_on_success and then does some other stuff with another model and causes an exception. Oops, when control returned to commit_on_success from the model method the transaction was committed and now the view errors out changing my view to all-or-some instead of all-or-nothing. This isn't limited to views. I may have nested operations going on which all lots_o_foo_or_nothing() uses commit_on_success and calls all_or_nothing_1() and all_or_nothing_2() which are both wrapped in commit_on_success. If lots_o_foo_or_nothing() errors out the sub function calls will have already committed their transactions to the DB, logically corrupting my data.

Is there a way around this? Again, pardon me, if I'm misunderstanding something, but it seems this is the behavior I've witnessed, and a way around it would be a great convenience.

Upvotes: 3

Views: 912

Answers (1)

Jerzyk
Jerzyk

Reputation: 3752

not a final solution but an idea based on this snippet (which is good idea per se)

this plus savepoints can create nice solution: a decorator, which will be aware if transaction is inside other transaction (and if it is, is using savepoints instead of transactions).

Upvotes: 2

Related Questions