Index: django/db/models/base.py
===================================================================
--- django/db/models/base.py	(revision 9084)
+++ django/db/models/base.py	(working copy)
@@ -14,7 +14,7 @@
 from django.db.models.fields.related import OneToOneRel, ManyToOneRel, OneToOneField
 from django.db.models.query import delete_objects, Q, CollectedObjects
 from django.db.models.options import Options
-from django.db import connection, transaction, DatabaseError
+from django.db import connection, transaction, DatabaseError, IntegrityError
 from django.db.models import signals
 from django.db.models.loading import register_models, get_model
 from django.utils.functional import curry
@@ -304,8 +304,15 @@
         if force_insert and force_update:
             raise ValueError("Cannot force both insert and updating in "
                     "model saving.")
-        self.save_base(force_insert=force_insert, force_update=force_update)
 
+        try:
+            sid = transaction.savepoint()
+            self.save_base(force_insert=force_insert, force_update=force_update)
+            transaction.savepoint_commit(sid)
+        except IntegrityError:
+            transaction.savepoint_rollback(sid)
+            raise
+
     save.alters_data = True
 
     def save_base(self, raw=False, cls=None, force_insert=False,
Index: django/db/models/query.py
===================================================================
--- django/db/models/query.py	(revision 9084)
+++ django/db/models/query.py	(working copy)
@@ -329,12 +329,9 @@
                 params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
                 params.update(defaults)
                 obj = self.model(**params)
-                sid = transaction.savepoint()
                 obj.save(force_insert=True)
-                transaction.savepoint_commit(sid)
                 return obj, True
             except IntegrityError, e:
-                transaction.savepoint_rollback(sid)
                 try:
                     return self.get(**kwargs), False
                 except self.model.DoesNotExist:
Index: django/db/backends/__init__.py
===================================================================
--- django/db/backends/__init__.py	(revision 9084)
+++ django/db/backends/__init__.py	(working copy)
@@ -34,17 +34,20 @@
     def _savepoint(self, sid):
         if not self.features.uses_savepoints:
             return
-        self.connection.cursor().execute(self.ops.savepoint_create_sql(sid))
+        if self.connection is not None:
+            self.connection.cursor().execute(self.ops.savepoint_create_sql(sid))
 
     def _savepoint_rollback(self, sid):
         if not self.features.uses_savepoints:
             return
-        self.connection.cursor().execute(self.ops.savepoint_rollback_sql(sid))
+        if self.connection is not None:
+            self.connection.cursor().execute(self.ops.savepoint_rollback_sql(sid))
 
     def _savepoint_commit(self, sid):
         if not self.features.uses_savepoints:
             return
-        self.connection.cursor().execute(self.ops.savepoint_commit_sql(sid))
+        if self.connection is not None:
+            self.connection.cursor().execute(self.ops.savepoint_commit_sql(sid))
 
     def close(self):
         if self.connection is not None:
Index: django/contrib/sessions/backends/db.py
===================================================================
--- django/contrib/sessions/backends/db.py	(revision 9084)
+++ django/contrib/sessions/backends/db.py	(working copy)
@@ -53,12 +53,10 @@
             session_data = self.encode(self._get_session(no_load=must_create)),
             expire_date = self.get_expiry_date()
         )
-        sid = transaction.savepoint()
         try:
             obj.save(force_insert=must_create)
         except IntegrityError:
             if must_create:
-                transaction.savepoint_rollback(sid)
                 raise CreateError
             raise
 
Index: tests/modeltests/force_insert_update/models.py
===================================================================
--- tests/modeltests/force_insert_update/models.py	(revision 9084)
+++ tests/modeltests/force_insert_update/models.py	(working copy)
@@ -40,7 +40,6 @@
 >>> c1.save(force_insert=True)
 
 # Won't work because we can't insert a pk of the same value.
->>> sid = transaction.savepoint()
 >>> c.value = 5
 >>> try:
 ...     c.save(force_insert=True)
@@ -50,7 +49,6 @@
 ...     else:
 ...         print "Fail with %s" % type(e)
 Pass
->>> transaction.savepoint_rollback(sid)
 
 # Trying to update should still fail, even with manual primary keys, if the
 # data isn't in the database already.
Index: tests/modeltests/one_to_one/models.py
===================================================================
--- tests/modeltests/one_to_one/models.py	(revision 9084)
+++ tests/modeltests/one_to_one/models.py	(working copy)
@@ -178,7 +178,6 @@
 
 # This will fail because each one-to-one field must be unique (and link2=o1 was
 # used for x1, above).
->>> sid = transaction.savepoint()
 >>> try:
 ...     MultiModel(link1=p2, link2=o1, name="x1").save()
 ... except Exception, e:
@@ -187,6 +186,5 @@
 ...     else:
 ...         print "Fail with %s" % type(e)
 Pass
->>> transaction.savepoint_rollback(sid)
 
 """}
Index: tests/modeltests/custom_pk/models.py
===================================================================
--- tests/modeltests/custom_pk/models.py	(revision 9084)
+++ tests/modeltests/custom_pk/models.py	(working copy)
@@ -110,12 +110,9 @@
 # The primary key must also obviously be unique, so trying to create a new
 # object with the same primary key will fail.
 >>> try:
-...    sid = transaction.savepoint()
 ...    Employee.objects.create(employee_code=123, first_name='Fred', last_name='Jones')
-...    transaction.savepoint_commit(sid)
 ... except Exception, e:
 ...    if isinstance(e, IntegrityError):
-...        transaction.savepoint_rollback(sid)
 ...        print "Pass"
 ...    else:
 ...        print "Fail with %s" % type(e)
@@ -131,14 +128,11 @@
 # The primary key must be specified, so an error is raised if you try to create
 # an object without it.
 >>> try:
-...     sid = transaction.savepoint()
 ...     Employee.objects.create(first_name='Tom', last_name='Smith')
 ...     print 'hello'
-...     transaction.savepoint_commit(sid)
 ...     print 'hello2'
 ... except Exception, e:
 ...     if isinstance(e, IntegrityError):
-...         transaction.savepoint_rollback(sid)
 ...         print "Pass"
 ...     else:
 ...         print "Fail with %s" % type(e)
