try/finally question

Paul Rubin phr-n2002b at NOSPAMnightsong.com
Wed Jul 10 16:39:16 EDT 2002


Erno Kuusela <erno-news at erno.iki.fi> writes:
> | So the obvious way to use it is:
> 
> |    try:
> |       db.begin()
> |       x = db.do_action(first_thing)
> |       y = db.do_action(second_thing)
> |       db.commit()
> |    finally:
> |       db.cancel()
> 
> | The trouble is db.cancel() is an ordinary method call--it's not atomic
> | in the interpreter.  It can be interrupted and blast out of the
> | finally block before finishing, and then control returns to some
> | higher level with the database still locked.
> 
> would it be different from the an interrupt coming
> at any point between the begin and the commit?

If an interrupt comes between the begin and the commit, the idea is that
the finally clause runs and db.cancel() releases the lock.

> if you want to do database transactions in the
> signal handler, you will probably get an error if you try to
> begin() before closing the previous transaction, but that same
> problem would be in the try block too.

I don't want to do database transactions in a signal handler.  I just
want to run db.cancel (which discards the pending changes and releases
the lock) atomically.

> if you never call neither commit or cancel but just exit, the effect
> in all the systems i have seen is effectively the same as calling
> cancel.

db here isn't a wrapper around a remote SQL connection.  It's just
something that serializes access to a dbm database in the same process.

More generally though, this seems like a deficiency in Python.  In
Java I believe that this issue can be solved by a synchronized object,
but Python doesn't have those.



More information about the Python-list mailing list