diff -r 09437beebc4e django/db/models/query.py
--- a/django/db/models/query.py	Sun Nov 13 15:09:08 2011 +0000
+++ b/django/db/models/query.py	Sun Nov 13 11:17:03 2011 -0500
@@ -394,18 +394,32 @@
         self._for_write = True
         connection = connections[self.db]
         fields = self.model._meta.local_fields
-        if (connection.features.can_combine_inserts_with_and_without_auto_increment_pk
-            and self.model._meta.has_auto_field):
-            self.model._base_manager._insert(objs, fields=fields, using=self.db)
+        if not transaction.is_managed(using=self.db):
+            transaction.enter_transaction_management(using=self.db)
+            forced_managed = True
         else:
-            objs_with_pk, objs_without_pk = partition(
-                lambda o: o.pk is None,
-                objs
-            )
-            if objs_with_pk:
-                self.model._base_manager._insert(objs_with_pk, fields=fields, using=self.db)
-            if objs_without_pk:
-                self.model._base_manager._insert(objs_without_pk, fields=[f for f in fields if not isinstance(f, AutoField)], using=self.db)
+            forced_managed = False
+        try:
+            if (connection.features.can_combine_inserts_with_and_without_auto_increment_pk
+                and self.model._meta.has_auto_field):
+                self.model._base_manager._insert(objs, fields=fields, using=self.db)
+            else:
+                objs_with_pk, objs_without_pk = partition(
+                    lambda o: o.pk is None,
+                    objs
+                )
+                if objs_with_pk:
+                    self.model._base_manager._insert(objs_with_pk, fields=fields, using=self.db)
+                if objs_without_pk:
+                    self.model._base_manager._insert(objs_without_pk, fields=[f for f in fields if not isinstance(f, AutoField)], using=self.db)
+            if forced_managed:
+                transaction.commit(using=self.db)
+            else:
+                transaction.commit_unless_managed(using=self.db)
+        finally:
+            if forced_managed:
+                transaction.leave_transaction_management(using=self.db)
+
         return objs
 
     def get_or_create(self, **kwargs):
diff -r 09437beebc4e tests/regressiontests/transactions_regress/models.py
--- a/tests/regressiontests/transactions_regress/models.py	Sun Nov 13 15:09:08 2011 +0000
+++ b/tests/regressiontests/transactions_regress/models.py	Sun Nov 13 11:17:03 2011 -0500
@@ -2,3 +2,9 @@
 
 class Mod(models.Model):
     fld = models.IntegerField()
+
+class M2mA(models.Model):
+    others = models.ManyToManyField('M2mB')
+
+class M2mB(models.Model):
+    fld = models.IntegerField()
diff -r 09437beebc4e tests/regressiontests/transactions_regress/tests.py
--- a/tests/regressiontests/transactions_regress/tests.py	Sun Nov 13 15:09:08 2011 +0000
+++ b/tests/regressiontests/transactions_regress/tests.py	Sun Nov 13 11:17:03 2011 -0500
@@ -5,7 +5,7 @@
 from django.db.transaction import commit_on_success, commit_manually, TransactionManagementError
 from django.test import TransactionTestCase, skipUnlessDBFeature
 
-from .models import Mod
+from .models import Mod, M2mA, M2mB
 
 
 class TestTransactionClosing(TransactionTestCase):
@@ -164,3 +164,15 @@
             _ = User.objects.all()[0]
         except:
             self.fail("A transaction consisting of a failed operation was not closed.")
+
+class TestManyToManyAddTransaction(TransactionTestCase):
+    def test_manyrelated_add_commit(self):
+        """test for 16818"""
+        a = M2mA.objects.create()
+        b = M2mB.objects.create(fld=10)
+        a.others.add(b)
+        # We're in a TransactionTestCase and have not changed transaction behavior from
+        # default of "autocommit", so this rollback should not actually do anything. If it
+        # does in fact un-do our add, that's a bug that the bulk insert was not auto-committed.
+        transaction.rollback()
+        self.assertQuerysetEqual(a.others.all(),['<M2mB: M2mB object>'])
