[1.5.x] Removed try-except in django.db.close_connection()

The reason was that the except clause needed to remove a connection
from the django.db.connections dict, but other parts of Django do not
expect this to happen. In addition the except clause was silently
swallowing the exception messages.

Refs #19707, special thanks to Carl Meyer for pointing out that this
approach should be taken.
This commit is contained in:
Anssi Kääriäinen 2013-02-12 23:11:22 +02:00
parent 77f6eb2a60
commit 743263a105
3 changed files with 15 additions and 19 deletions

View File

@ -45,14 +45,11 @@ def close_connection(**kwargs):
# Avoid circular imports # Avoid circular imports
from django.db import transaction from django.db import transaction
for conn in connections: for conn in connections:
try: # If an error happens here the connection will be left in broken
transaction.abort(conn) # state. Once a good db connection is again available, the
connections[conn].close() # connection state will be cleaned up.
except Exception: transaction.abort(conn)
# The connection's state is unknown, so it has to be connections[conn].close()
# abandoned. This could happen for example if the network
# connection has a failure.
del connections[conn]
signals.request_finished.connect(close_connection) signals.request_finished.connect(close_connection)
# Register an event that resets connection.queries # Register an event that resets connection.queries

View File

@ -98,9 +98,6 @@ class ConnectionHandler(object):
def __setitem__(self, key, value): def __setitem__(self, key, value):
setattr(self._connections, key, value) setattr(self._connections, key, value)
def __delitem__(self, key):
delattr(self._connections, key)
def __iter__(self): def __iter__(self):
return iter(self.databases) return iter(self.databases)

View File

@ -562,9 +562,6 @@ class TransactionRequestTests(TransactionTestCase):
'This test will close the connection, in-memory ' 'This test will close the connection, in-memory '
'sqlite connections must not be closed.') 'sqlite connections must not be closed.')
def test_request_finished_failed_connection(self): def test_request_finished_failed_connection(self):
# See comments in test_request_finished_db_state() for the self.client
# usage.
response = self.client.get('/')
conn = connections[DEFAULT_DB_ALIAS] conn = connections[DEFAULT_DB_ALIAS]
conn.enter_transaction_management() conn.enter_transaction_management()
conn.managed(True) conn.managed(True)
@ -574,9 +571,14 @@ class TransactionRequestTests(TransactionTestCase):
def fail_horribly(): def fail_horribly():
raise Exception("Horrible failure!") raise Exception("Horrible failure!")
conn._rollback = fail_horribly conn._rollback = fail_horribly
signals.request_finished.send(sender=response._handler_class) try:
# As even rollback wasn't possible the connection wrapper itself was with self.assertRaises(Exception):
# abandoned. Accessing the connections[alias] will create a new signals.request_finished.send(sender=self.__class__)
# connection wrapper, whch must be different than the original one. # The connection's state wasn't cleaned up
self.assertIsNot(conn, connections[DEFAULT_DB_ALIAS]) self.assertTrue(len(connection.transaction_state), 1)
finally:
del conn._rollback
# The connection will be cleaned on next request where the conn
# works again.
signals.request_finished.send(sender=self.__class__)
self.assertEqual(len(connection.transaction_state), 0) self.assertEqual(len(connection.transaction_state), 0)