Ability to skip nested transactions

I would like to consult something with you guys. I have found myself in a situation where my code produces a lot of savepoints which, at least in my case, could theoretically be skipped. Here comes an example showcasing the problem:

@transaction.atomic
def create_many_things():
    # If any of following fails, I want to rollback the entire transaction.
    # Having these nested transactions is not necessary in my case.
    create_something_1()
    create_something_2()


@transation.atomic
def create_something_1():
    # Can be used on its own and requires to be wrapped in a transaction.
    ...


@transation.atomic
def create_something_2():
    # Can be used on its own and requires to be wrapped in a transaction.
    ...

In my case this is a bit more complicated than this. It results in quite many GET/UPDATE/INSERT queries, which is fine, but it also generates a lot of SAVEPOINT/RELEASE SAVEPOINT queries, which seem to me to be unnecessary, at least in my case. If any of these create_something-functions fail, I want to rollback the entire thing, which seems to be impossible to do, based on what I see in the Atomic context-decorator.

What do you think about about introducing a way of skipping nested transactions? It is something that would need to be used with care, but could possibly give people a way of drastically improving performance in cases like these.

I think you want atomic(savepoint=False) ? This disables creating of savepoints if already inside a transaction.

Per docs:

You can disable the creation of savepoints for inner blocks by setting the savepoint argument to False . If an exception occurs, Django will perform the rollback when exiting the first parent block with a savepoint if there is one, and the outermost block otherwise. Atomicity is still guaranteed by the outer transaction. This option should only be used if the overhead of savepoints is noticeable. It has the drawback of breaking the error handling described above.

1 Like

I’d also like to say - thank you for thinking so much about transactions. Most projects I’ve taken a peek at have limited or zero usage of transactions, and plenty of “weird rare concurrency bugs” to go along with this.