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

31 views
Skip to first unread message

Willem de Jonge

unread,
Sep 2, 2011, 6:46:40 AM9/2/11
to django...@googlegroups.com
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


Reply all
Reply to author
Forward
0 new messages