Loading django/contrib/auth/handlers/modwsgi.py +2 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ def check_password(environ, username, password): return None return user.check_password(password) finally: db.close_connection() db.close_old_connections() def groups_for_user(environ, username): """ Loading @@ -44,4 +44,4 @@ def groups_for_user(environ, username): return [] return [force_bytes(group.name) for group in user.groups.all()] finally: db.close_connection() db.close_old_connections() django/db/__init__.py +16 −5 Original line number Diff line number Diff line Loading @@ -42,9 +42,10 @@ class DefaultConnectionProxy(object): connection = DefaultConnectionProxy() backend = load_backend(connection.settings_dict['ENGINE']) # Register an event that closes the database connection # when a Django request is finished. def close_connection(**kwargs): warnings.warn( "close_connection is superseded by close_old_connections.", PendingDeprecationWarning, stacklevel=2) # Avoid circular imports from django.db import transaction for conn in connections: Loading @@ -53,15 +54,25 @@ def close_connection(**kwargs): # connection state will be cleaned up. transaction.abort(conn) connections[conn].close() signals.request_finished.connect(close_connection) # Register an event that resets connection.queries # when a Django request is started. # Register an event to reset saved queries when a Django request is started. def reset_queries(**kwargs): for conn in connections.all(): conn.queries = [] signals.request_started.connect(reset_queries) # Register an event to reset transaction state and close connections past # their lifetime. NB: abort() doesn't do anything outside of a transaction. def close_old_connections(**kwargs): for conn in connections.all(): try: conn.abort() except DatabaseError: pass conn.close_if_unusable_or_obsolete() signals.request_started.connect(close_old_connections) signals.request_finished.connect(close_old_connections) # Register an event that rolls back the connections # when a Django request has an exception. def _rollback_on_exception(**kwargs): Loading django/db/backends/__init__.py +31 −1 Original line number Diff line number Diff line import datetime import time from django.db.utils import DatabaseError Loading Loading @@ -49,6 +50,10 @@ class BaseDatabaseWrapper(object): self._thread_ident = thread.get_ident() self.allow_thread_sharing = allow_thread_sharing # Connection termination related attributes self.close_at = None self.errors_occurred = False def __eq__(self, other): return self.alias == other.alias Loading @@ -59,7 +64,7 @@ class BaseDatabaseWrapper(object): return hash(self.alias) def wrap_database_errors(self): return DatabaseErrorWrapper(self.Database) return DatabaseErrorWrapper(self) def get_connection_params(self): raise NotImplementedError Loading @@ -76,6 +81,11 @@ class BaseDatabaseWrapper(object): def _cursor(self): with self.wrap_database_errors(): if self.connection is None: # Reset parameters defining when to close the connection max_age = self.settings_dict['CONN_MAX_AGE'] self.close_at = None if max_age is None else time.time() + max_age self.errors_occurred = False # Establish the connection conn_params = self.get_connection_params() self.connection = self.get_new_connection(conn_params) self.init_connection_state() Loading Loading @@ -351,6 +361,26 @@ class BaseDatabaseWrapper(object): self.connection = None self.set_clean() def close_if_unusable_or_obsolete(self): if self.connection is not None: if self.errors_occurred: if self.is_usable(): self.errors_occurred = False else: self.close() return if self.close_at is not None and time.time() >= self.close_at: self.close() return def is_usable(self): """ Test if the database connection is usable. This function may assume that self.connection is not None. """ raise NotImplementedError def cursor(self): self.validate_thread_sharing() if (self.use_debug_cursor or Loading django/db/backends/mysql/base.py +8 −0 Original line number Diff line number Diff line Loading @@ -439,6 +439,14 @@ class DatabaseWrapper(BaseDatabaseWrapper): cursor = self.connection.cursor() return CursorWrapper(cursor) def is_usable(self): try: self.connection.ping() except DatabaseError: return False else: return True def _rollback(self): try: BaseDatabaseWrapper._rollback(self) Loading django/db/backends/oracle/base.py +12 −0 Original line number Diff line number Diff line Loading @@ -598,6 +598,18 @@ class DatabaseWrapper(BaseDatabaseWrapper): # stmtcachesize is available only in 4.3.2 and up. pass def is_usable(self): try: if hasattr(self.connection, 'ping'): # Oracle 10g R2 and higher self.connection.ping() else: # Use a cx_Oracle cursor directly, bypassing Django's utilities. self.connection.cursor().execute("SELECT 1 FROM DUAL") except DatabaseError: return False else: return True # Oracle doesn't support savepoint commits. Ignore them. def _savepoint_commit(self, sid): pass Loading Loading
django/contrib/auth/handlers/modwsgi.py +2 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ def check_password(environ, username, password): return None return user.check_password(password) finally: db.close_connection() db.close_old_connections() def groups_for_user(environ, username): """ Loading @@ -44,4 +44,4 @@ def groups_for_user(environ, username): return [] return [force_bytes(group.name) for group in user.groups.all()] finally: db.close_connection() db.close_old_connections()
django/db/__init__.py +16 −5 Original line number Diff line number Diff line Loading @@ -42,9 +42,10 @@ class DefaultConnectionProxy(object): connection = DefaultConnectionProxy() backend = load_backend(connection.settings_dict['ENGINE']) # Register an event that closes the database connection # when a Django request is finished. def close_connection(**kwargs): warnings.warn( "close_connection is superseded by close_old_connections.", PendingDeprecationWarning, stacklevel=2) # Avoid circular imports from django.db import transaction for conn in connections: Loading @@ -53,15 +54,25 @@ def close_connection(**kwargs): # connection state will be cleaned up. transaction.abort(conn) connections[conn].close() signals.request_finished.connect(close_connection) # Register an event that resets connection.queries # when a Django request is started. # Register an event to reset saved queries when a Django request is started. def reset_queries(**kwargs): for conn in connections.all(): conn.queries = [] signals.request_started.connect(reset_queries) # Register an event to reset transaction state and close connections past # their lifetime. NB: abort() doesn't do anything outside of a transaction. def close_old_connections(**kwargs): for conn in connections.all(): try: conn.abort() except DatabaseError: pass conn.close_if_unusable_or_obsolete() signals.request_started.connect(close_old_connections) signals.request_finished.connect(close_old_connections) # Register an event that rolls back the connections # when a Django request has an exception. def _rollback_on_exception(**kwargs): Loading
django/db/backends/__init__.py +31 −1 Original line number Diff line number Diff line import datetime import time from django.db.utils import DatabaseError Loading Loading @@ -49,6 +50,10 @@ class BaseDatabaseWrapper(object): self._thread_ident = thread.get_ident() self.allow_thread_sharing = allow_thread_sharing # Connection termination related attributes self.close_at = None self.errors_occurred = False def __eq__(self, other): return self.alias == other.alias Loading @@ -59,7 +64,7 @@ class BaseDatabaseWrapper(object): return hash(self.alias) def wrap_database_errors(self): return DatabaseErrorWrapper(self.Database) return DatabaseErrorWrapper(self) def get_connection_params(self): raise NotImplementedError Loading @@ -76,6 +81,11 @@ class BaseDatabaseWrapper(object): def _cursor(self): with self.wrap_database_errors(): if self.connection is None: # Reset parameters defining when to close the connection max_age = self.settings_dict['CONN_MAX_AGE'] self.close_at = None if max_age is None else time.time() + max_age self.errors_occurred = False # Establish the connection conn_params = self.get_connection_params() self.connection = self.get_new_connection(conn_params) self.init_connection_state() Loading Loading @@ -351,6 +361,26 @@ class BaseDatabaseWrapper(object): self.connection = None self.set_clean() def close_if_unusable_or_obsolete(self): if self.connection is not None: if self.errors_occurred: if self.is_usable(): self.errors_occurred = False else: self.close() return if self.close_at is not None and time.time() >= self.close_at: self.close() return def is_usable(self): """ Test if the database connection is usable. This function may assume that self.connection is not None. """ raise NotImplementedError def cursor(self): self.validate_thread_sharing() if (self.use_debug_cursor or Loading
django/db/backends/mysql/base.py +8 −0 Original line number Diff line number Diff line Loading @@ -439,6 +439,14 @@ class DatabaseWrapper(BaseDatabaseWrapper): cursor = self.connection.cursor() return CursorWrapper(cursor) def is_usable(self): try: self.connection.ping() except DatabaseError: return False else: return True def _rollback(self): try: BaseDatabaseWrapper._rollback(self) Loading
django/db/backends/oracle/base.py +12 −0 Original line number Diff line number Diff line Loading @@ -598,6 +598,18 @@ class DatabaseWrapper(BaseDatabaseWrapper): # stmtcachesize is available only in 4.3.2 and up. pass def is_usable(self): try: if hasattr(self.connection, 'ping'): # Oracle 10g R2 and higher self.connection.ping() else: # Use a cx_Oracle cursor directly, bypassing Django's utilities. self.connection.cursor().execute("SELECT 1 FROM DUAL") except DatabaseError: return False else: return True # Oracle doesn't support savepoint commits. Ignore them. def _savepoint_commit(self, sid): pass Loading