Index: django/db/backends/oracle/base.py
===================================================================
--- django/db/backends/oracle/base.py	(revision 10578)
+++ django/db/backends/oracle/base.py	(working copy)
@@ -273,6 +273,9 @@
         'iendswith': "LIKEC UPPER(%s) ESCAPE '\\'",
     }
     oracle_version = None
+    _pool_defaults = {'SESSION_POOL_MIN': 1,
+                      'SESSION_POOL_MAX': 3,
+                      'SESSION_POOL_INCREMENT': 1,}
 
     def __init__(self, *args, **kwargs):
         super(DatabaseWrapper, self).__init__(*args, **kwargs)
@@ -283,7 +286,54 @@
         self.creation = DatabaseCreation(self)
         self.introspection = DatabaseIntrospection(self)
         self.validation = BaseDatabaseValidation()
+        
+        # Fetch connection pool settings
+        opts = self.settings_dict['DATABASE_OPTIONS']
+        if not isinstance(opts, dict):
+            # Insurance against foolish users...
+            opts = {}
+        if opts.get('SESSION_POOL', False):
+            self._use_pool = True
+            self._pool_settings = dict(self._pool_defaults)
+            self._pool_settings.update(opts)
+        else:
+            self._use_pool = False
+    
+    def _get_pool (self):
+        if not hasattr (self.__class__, '_pool'):
+            settings_dict = self.settings_dict
+            Database.OPT_Threading = 1
+            if len(settings_dict['DATABASE_HOST'].strip()) == 0:
+                settings_dict['DATABASE_HOST'] = 'localhost'
+            if len(settings_dict['DATABASE_PORT'].strip()) != 0:
+                dsn = Database.makedsn(settings_dict['DATABASE_HOST'],
+                                       int(settings_dict['DATABASE_PORT']),
+                                       settings_dict['DATABASE_NAME'])
+                p = Database.SessionPool(settings_dict['DATABASE_USER'],
+                                         settings_dict['DATABASE_PASSWORD'],
+                                         dsn,
+                                         self._pool_settings['SESSION_POOL_MIN'],
+                                         self._pool_settings['SESSION_POOL_MAX'],
+                                         self._pool_settings['SESSION_POOL_INCREMENT'],
+                                         threaded = True)
+            else:
+                p = Database.SessionPool(settings_dict['DATABASE_USER'],
+                                         settings_dict['DATABASE_PASSWORD'],
+                                         settings_dict['DATABASE_NAME'],
+                                         self._pool_settings['SESSION_POOL_MIN'],
+                                         self._pool_settings['SESSION_POOL_MAX'],
+                                         self._pool_settings['SESSION_POOL_INCREMENT'],
+                                         threaded = True)
+            setattr(self.__class__, '_pool', p)
+            # TODO I think the init stuff only needs to happen once per pool,
+            # but it may be once per connection...
+            conn = p.acquire()
+            self._init_oracle_settings(conn)
+            p.release(conn)
+        return getattr(self.__class__, '_pool')
 
+    pool = property (_get_pool)
+
     def _valid_connection(self):
         return self.connection is not None
 
@@ -300,41 +350,60 @@
         return "%s/%s@%s" % (settings_dict['DATABASE_USER'],
                              settings_dict['DATABASE_PASSWORD'], dsn)
 
+    def _init_oracle_settings(self, connection):
+        cursor = FormatStylePlaceholderCursor(connection)
+        # Set oracle date to ansi date format.  This only needs to execute
+        # once when we create a new connection. We also set the Territory
+        # to 'AMERICA' which forces Sunday to evaluate to a '1' in TO_CHAR().
+        cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' "
+                       "NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF' "
+                       "NLS_TERRITORY = 'AMERICA'")
+        try:
+            self.oracle_version = int(connection.version.split('.')[0])
+            # There's no way for the DatabaseOperations class to know the
+            # currently active Oracle version, so we do some setups here.
+            # TODO: Multi-db support will need a better solution (a way to
+            # communicate the current version).
+            if self.oracle_version <= 9:
+                self.ops.regex_lookup = self.ops.regex_lookup_9
+            else:
+                self.ops.regex_lookup = self.ops.regex_lookup_10
+        except ValueError:
+            pass
+        return cursor
+
     def _cursor(self):
         cursor = None
         if not self._valid_connection():
-            conn_string = self._connect_string()
-            self.connection = Database.connect(conn_string, **self.settings_dict['DATABASE_OPTIONS'])
-            cursor = FormatStylePlaceholderCursor(self.connection)
-            # Set oracle date to ansi date format.  This only needs to execute
-            # once when we create a new connection. We also set the Territory
-            # to 'AMERICA' which forces Sunday to evaluate to a '1' in TO_CHAR().
-            cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' "
-                           "NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF' "
-                           "NLS_TERRITORY = 'AMERICA'")
+            if self._use_pool and self.pool is not None:
+                self.connection = self.pool.acquire()
+            else:
+                    self.connection = Database.connect(self._connect_string()
+                        **self.settings_dict['DATABASE_OPTIONS'])
+                    cursor = self._init_oracle_settings(self.connection)
             try:
-                self.oracle_version = int(self.connection.version.split('.')[0])
-                # There's no way for the DatabaseOperations class to know the
-                # currently active Oracle version, so we do some setups here.
-                # TODO: Multi-db support will need a better solution (a way to
-                # communicate the current version).
-                if self.oracle_version <= 9:
-                    self.ops.regex_lookup = self.ops.regex_lookup_9
-                else:
-                    self.ops.regex_lookup = self.ops.regex_lookup_10
-            except ValueError:
-                pass
-            try:
                 self.connection.stmtcachesize = 20
             except:
                 # Django docs specify cx_Oracle version 4.3.1 or higher, but
                 # stmtcachesize is available only in 4.3.2 and up.
                 pass
+            # TODO Does pulling a connection from the pool count as "creation"?
             connection_created.send(sender=self.__class__)
         if not cursor:
             cursor = FormatStylePlaceholderCursor(self.connection)
         return cursor
 
+    def close(self):
+       from django.conf import settings
+       if self._use_pool:
+           if self.connection is not None:
+               self.pool.release(self.connection)
+               self.connection = None
+       else:
+           if self.connection is not None:
+               self.connection.close()
+               self.connection = None
+
     # Oracle doesn't support savepoint commits.  Ignore them.
     def _savepoint_commit(self, sid):
         pass
