On Mon, Jul 18, 2011 at 3:52 PM, M.-A. Lemburg <m...@egenix.com> wrote: > Vernon Cole wrote: >> A cursor and/or a >> connection should probably be context managers, so that they will work in a >> "with" statement. > > This is was discussed before and it should probably go into > the DB API in some form. > > I'm no particular fan of hiding transactions in context > managers, though. In practice this often causes problems, since > you usually want to apply error handling logic in case of > problems, other than simply issuing a .rollback().
For most of the applications I work with, the transaction handling has been delegated to function decorators, or have it hidden in the framework (e.g. Django's TransactionMiddleware). If there are clean up tasks that need to happen on transaction commit or roll back (e.g. deleting a file on a failed transaction), then using a global transaction manager like Zope's transaction module seems to be a good fit. For transaction retry or error reporting, I haven't seen much benefit in leaving the transaction in an "open by broken" state over cleaning up with a rollback. > Another problem is that the connections used in a with > statement will usually have already started a transaction > before entering the context, so the .rollback() would > remove more than just the things added in the with > context. None of the databases I've worked with fit the Python DB API's "implicit begin" behaviour for transactions, so their adapters have all needed to run a simple state machine to determine when it is necessary to start a transaction. So it would be pretty easy for them to raise an error if an attempt was made to use the context manager when a transaction was already in progress. If all adapters that support transactions function like that, then I think it would be sensible to require them to raise an error in that case. If they don't raise an error, you know that someone somewhere is going to write code like the following: with transaction: # do stuff with transaction: # do more stuff ... and wonder why things break. > There's also the problem of intuitive use: some users will > likely expect the connection to also be closed when leaving > the context - much like what happens with files. If that is a concern, you could require a method call to get the context manager rather than making the connection itself a context manager. For example: with connection.begin_transaction(): ... > The case for having cursors automatically closed by > is not problematic I don't think it makes sense to make cursors behave as context managers for transaction handling. Transactions are a connection level concept affecting all the cursors for the connection, so this would just confuse matters and lead to coding errors. James. _______________________________________________ DB-SIG maillist - DB-SIG@python.org http://mail.python.org/mailman/listinfo/db-sig