Index: django/db/models/sql/query.py
===================================================================
--- django/db/models/sql/query.py	(revision 7509)
+++ django/db/models/sql/query.py	(working copy)
@@ -67,6 +67,7 @@
         self.order_by = []
         self.low_mark, self.high_mark = 0, None  # Used for offset/limit
         self.distinct = False
+        self.select_for_update = False
         self.select_related = False
         self.related_select_cols = []
 
@@ -173,6 +174,7 @@
         obj.order_by = self.order_by[:]
         obj.low_mark, obj.high_mark = self.low_mark, self.high_mark
         obj.distinct = self.distinct
+        obj.select_for_update = self.select_for_update
         obj.select_related = self.select_related
         obj.related_select_cols = []
         obj.max_depth = self.max_depth
@@ -211,6 +213,7 @@
         obj = self.clone()
         obj.clear_ordering(True)
         obj.clear_limits()
+        obj.select_for_update = False
         obj.select_related = False
         obj.related_select_cols = []
         obj.related_select_fields = []
@@ -290,6 +293,9 @@
                         result.append('LIMIT %d' % val)
                 result.append('OFFSET %d' % self.low_mark)
 
+        if self.select_for_update:
+            result.append("%s" % self.connection.ops.for_update_sql())
+
         params.extend(self.extra_params)
         return ' '.join(result), tuple(params)
 
Index: django/db/models/manager.py
===================================================================
--- django/db/models/manager.py	(revision 7509)
+++ django/db/models/manager.py	(working copy)
@@ -108,6 +108,9 @@
     def order_by(self, *args, **kwargs):
         return self.get_query_set().order_by(*args, **kwargs)
 
+    def select_for_update(self, *args, **kwargs): 
+        return self.get_query_set().select_for_update(*args, **kwargs)
+        
     def select_related(self, *args, **kwargs):
         return self.get_query_set().select_related(*args, **kwargs)
 
Index: django/db/models/query.py
===================================================================
--- django/db/models/query.py	(revision 7509)
+++ django/db/models/query.py	(working copy)
@@ -267,6 +267,7 @@
         del_query = self._clone()
 
         # Disable non-supported fields.
+        del_query.query.select_for_update = False
         del_query.query.select_related = False
         del_query.query.clear_ordering()
 
@@ -402,6 +403,15 @@
         else:
             return self._filter_or_exclude(None, **filter_obj)
 
+    def select_for_update(self):
+        """
+        Returns a new QuerySet instance that will select objects with a
+        FOR UPDATE lock.
+        """
+        obj = self._clone()
+        obj.query.select_for_update = True
+        return obj
+
     def select_related(self, *fields, **kwargs):
         """
         Returns a new QuerySet instance that will select related objects. If
Index: django/db/backends/sqlite3/base.py
===================================================================
--- django/db/backends/sqlite3/base.py	(revision 7509)
+++ django/db/backends/sqlite3/base.py	(working copy)
@@ -52,6 +52,10 @@
         # function django_date_trunc that's registered in connect().
         return 'django_date_trunc("%s", %s)' % (lookup_type.lower(), field_name)
 
+    def for_update_sql():
+        # sqlite does not support FOR UPDATE
+        return ''
+
     def drop_foreignkey_sql(self):
         return ""
 
@@ -171,3 +175,4 @@
         return bool(re.search(re_pattern, re_string))
     except:
         return False
+
Index: django/db/backends/__init__.py
===================================================================
--- django/db/backends/__init__.py	(revision 7509)
+++ django/db/backends/__init__.py	(working copy)
@@ -160,6 +160,12 @@
         """
         return cursor.lastrowid
 
+    def for_update_sql(self):
+        """
+        Return FOR UPDATE SQL clause to lock row for update
+        """
+        return 'FOR UPDATE' 
+
     def limit_offset_sql(self, limit, offset=None):
         """
         Returns a LIMIT/OFFSET SQL clause, given a limit and optional offset.
Index: tests/regressiontests/queries/models.py
===================================================================
--- tests/regressiontests/queries/models.py	(revision 7509)
+++ tests/regressiontests/queries/models.py	(working copy)
@@ -695,6 +695,14 @@
 >>> Item.objects.exclude(~Q(tags__name='t1', name='one'), name='two')
 [<Item: four>, <Item: one>, <Item: three>]
 
+Bug #2075
+Added FOR UPDATE functionality
+>>> t = Tag(name='for update test')
+>>> t.save()
+>>> tfound = Tag.objects.select_for_update().filter(name='for update test')
+>>> tfound.name = 'for update test 2'
+>>> tfound.save()
+
 Bug #7095
 Updates that are filtered on the model being updated are somewhat tricky to get
 in MySQL. This exercises that case.
Index: docs/db-api.txt
===================================================================
--- docs/db-api.txt	(revision 7509)
+++ docs/db-api.txt	(working copy)
@@ -1046,6 +1046,24 @@
 ``extra()`` is new. Previously, you could attempt to pass parameters for
 ``select`` in the ``params`` argument, but it worked very unreliably.
 
+select_for_update
+~~~~~~~~~~~~~~~~~
+
+**New in Django development version:**
+
+Most databases allow you to exclusively lock rows. To do this call the method
+select_for_update() to lock all rows returned by the query::
+
+    entry = Entry.objects.select_for_update().filter(headline__startswith="What")[:1]
+    ...
+    entry.save()
+
+Make sure to save the objects or commit the transaction in order to
+unlock the locks. In the case of using middleware, any locks will
+be released when the view returns and the transaction is committed. SQLite
+does not support an exclusive lock so this is simply ignored for SQLite.
+Other databases issue a ``FOR UPDATE``.
+
 QuerySet methods that do not return QuerySets
 ---------------------------------------------
 
