[DB-SIG] conn.close() idempotence

Daniele Varrazzo daniele.varrazzo at gmail.com
Wed Oct 19 10:47:12 CEST 2011


On Wed, Oct 19, 2011 at 8:59 AM, M.-A. Lemburg <mal at egenix.com> wrote:

>> risks to become a problem, with the close() that may raise an error
>> because the connection has been implicitly closed by a communication
>> error. Note that close() in itself often is a quite safe operation,
>> not involving database communication, so it is not expected to fail
>> and may not be well guarded.
>
> That last sentence is not quite correct: .close() issues an implicit
> .rollback() and usually also tells the database backend to free up
> resources maintained for the connection, so it does require communication
> with the backend.

If the rollback is implicit in the backend instead of in the driver,
the driver can just cut the communication with the server and obtain
the dbapi semantics without issuing a new command. While this is just
a trick when close() is called explicitly, it is about necessary on
del: not only sending a rollback is a complex operation to be executed
by __del__ (just because: it can fail and del would swallow the
exception, thing we don't like): in complex environments (such as
nonblocking aynchronous communication) pushing the rollback to the
server and reading its response implies interaction between other
python code and the connection being destroyed, whose results are at
best undetermined.


>> now, is conn.close() an "operation" on the connection? Even if it
>> doesn't involve server communication? I don't think an idempotent
>> close() violates this rule, so I'm really asking about an
>> interpretation of the DBAPI, not a change.
>
> See above. .close() does imply a few operations that can fail.
> You are basically suggesting to silence and ignore those exceptions.
> That's generally not a good idea, since the application may want
> to report those errors to the user or take some other action.

No, I'm not suggesting to silence exception: I'm suggesting to not
enforce an exception throw when it is not necessary.


> What we could do is expose an attribute connection.closed which
> gets set to True by a successful run of connection.close().
> That way you can test for the "unusable" state on a connection,
> e.g.
>
> if not connection.closed:
>     connection.close()

We already have such attribute as an extension. I am basically
suggesting this pattern to be implicit in the close() instead of
having people to code it everywhere.


-- Daniele


More information about the DB-SIG mailing list