Index: django/db/backends/oracle/base.py
===================================================================
--- django/db/backends/oracle/base.py	(revision 10832)
+++ 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)
@@ -284,6 +287,53 @@
         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,12 +350,8 @@
         return "%s/%s@%s" % (settings_dict['DATABASE_USER'],
                              settings_dict['DATABASE_PASSWORD'], dsn)
 
-    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)
+    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().
@@ -313,7 +359,7 @@
                            "NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF' "
                            "NLS_TERRITORY = 'AMERICA'")
             try:
-                self.oracle_version = int(self.connection.version.split('.')[0])
+            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
@@ -324,17 +370,40 @@
                     self.ops.regex_lookup = self.ops.regex_lookup_10
             except ValueError:
                 pass
+        return cursor
+
+    def _cursor(self):
+        cursor = None
+        if not self._valid_connection():
+            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.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
Index: django/db/backends/oracle/creation.py
===================================================================
--- django/db/backends/oracle/creation.py	(revision 10832)
+++ django/db/backends/oracle/creation.py	(working copy)
@@ -111,6 +111,10 @@
         settings.TEST_DATABASE_USER = settings.DATABASE_USER = self.connection.settings_dict["DATABASE_USER"] = TEST_DATABASE_USER
         settings.DATABASE_PASSWORD = self.connection.settings_dict["DATABASE_PASSWORD"] = TEST_DATABASE_PASSWD
 
+        if hasattr(self.connection, '_pool'):
+            self.connection.close()
+            del self.connection.__class__._pool
+
         return settings.DATABASE_NAME
 
     def _destroy_test_db(self, test_database_name, verbosity=1):
@@ -118,6 +122,11 @@
         Destroy a test database, prompting the user for confirmation if the
         database already exists. Returns the name of the test database created.
         """
+
+        if hasattr(self.connection, '_pool'):
+            self.connection.close()
+            del self.connection.__class__._pool
+
         TEST_DATABASE_NAME = self._test_database_name(settings)
         TEST_DATABASE_USER = self._test_database_user(settings)
         TEST_DATABASE_PASSWD = self._test_database_passwd(settings)
