Friday, September 2, 2011

Explicit transactions in non-web app, avoiding "idle in transaction"

Hi,

We are using the Django ORM model outside the web context in a long lived process.
This works quite well however the Postgres database connection is always "idle in transaction", which blocks other DB operations we need to do.

To fix this we use the database-level autocommit option () which gets rid of transactions, this works great.
Now we need to put some parts of our code in explicit transaction to ensure consistency, and this is the main question:

What is the correct way of doing explicit transactions in Django?

There is transaction.commit() and rollback() however there is no transaction.begin().

I found the enter_transaction_management() and leave_transaction_management() functions, which are used in the commit_on_succes decorator like this:

        transaction.enter_transaction_management()
        transaction.managed(True)

        # this could should be in a transaction
        ...

        transaction.commit()

        transaction.leave_transaction_management()

        # any DB operation here will automagically begin a new transaction, which we don't want

The above code suffers from the problem that any database operation that happens after it automagically will start a new transaction, again creating an idle transaction.
I found 2 ways to remedy this:

A) Remove the transaction.managed(True) like this:

        transaction.enter_transaction_management()

        # this could should be in a transaction
        ...

        transaction.commit()

        transaction.leave_transaction_management()

        # any DB operation here will NOT begin a new transaction

or

B) Match it with a transaction.managed(False) like this:

        transaction.enter_transaction_management()
        transaction.managed(True)

        # this could should be in a transaction
        ...

        transaction.commit()

        transaction.managed(False)
        transaction.leave_transaction_management()

        # any DB operation here will NOT begin a new transaction

What is the "correct" way to do this explicit transaction in Django, is it any of the above?

Any help would be appreciated.

Willem


--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/j3BZhKKM_rMJ.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

No comments:

Post a Comment