Ticket #2705: for_update_7510.patch

File for_update_7510.patch, 6.2 KB (added by sakyamuni, 16 years ago)

Corrected bug in test, modified documentation

  • django/db/models/sql/query.py

     
    6767        self.order_by = []
    6868        self.low_mark, self.high_mark = 0, None  # Used for offset/limit
    6969        self.distinct = False
     70        self.select_for_update = False
    7071        self.select_related = False
    7172        self.related_select_cols = []
    7273
     
    173174        obj.order_by = self.order_by[:]
    174175        obj.low_mark, obj.high_mark = self.low_mark, self.high_mark
    175176        obj.distinct = self.distinct
     177        obj.select_for_update = self.select_for_update
    176178        obj.select_related = self.select_related
    177179        obj.related_select_cols = []
    178180        obj.max_depth = self.max_depth
     
    211213        obj = self.clone()
    212214        obj.clear_ordering(True)
    213215        obj.clear_limits()
     216        obj.select_for_update = False
    214217        obj.select_related = False
    215218        obj.related_select_cols = []
    216219        obj.related_select_fields = []
     
    290293                        result.append('LIMIT %d' % val)
    291294                result.append('OFFSET %d' % self.low_mark)
    292295
     296        if self.select_for_update:
     297            result.append("%s" % self.connection.ops.for_update_sql())
     298
    293299        params.extend(self.extra_params)
    294300        return ' '.join(result), tuple(params)
    295301
  • django/db/models/manager.py

     
    108108    def order_by(self, *args, **kwargs):
    109109        return self.get_query_set().order_by(*args, **kwargs)
    110110
     111    def select_for_update(self, *args, **kwargs):
     112        return self.get_query_set().select_for_update(*args, **kwargs)
     113       
    111114    def select_related(self, *args, **kwargs):
    112115        return self.get_query_set().select_related(*args, **kwargs)
    113116
  • django/db/models/query.py

     
    267267        del_query = self._clone()
    268268
    269269        # Disable non-supported fields.
     270        del_query.query.select_for_update = False
    270271        del_query.query.select_related = False
    271272        del_query.query.clear_ordering()
    272273
     
    402403        else:
    403404            return self._filter_or_exclude(None, **filter_obj)
    404405
     406    def select_for_update(self):
     407        """
     408        Returns a new QuerySet instance that will select objects with a
     409        FOR UPDATE lock.
     410        """
     411        obj = self._clone()
     412        obj.query.select_for_update = True
     413        return obj
     414
    405415    def select_related(self, *fields, **kwargs):
    406416        """
    407417        Returns a new QuerySet instance that will select related objects. If
  • django/db/backends/sqlite3/base.py

     
    5252        # function django_date_trunc that's registered in connect().
    5353        return 'django_date_trunc("%s", %s)' % (lookup_type.lower(), field_name)
    5454
     55    def for_update_sql():
     56        # sqlite does not support FOR UPDATE
     57        return ''
     58
    5559    def drop_foreignkey_sql(self):
    5660        return ""
    5761
     
    171175        return bool(re.search(re_pattern, re_string))
    172176    except:
    173177        return False
     178
  • django/db/backends/__init__.py

     
    160160        """
    161161        return cursor.lastrowid
    162162
     163    def for_update_sql(self):
     164        """
     165        Return FOR UPDATE SQL clause to lock row for update
     166        """
     167        return 'FOR UPDATE'
     168
    163169    def limit_offset_sql(self, limit, offset=None):
    164170        """
    165171        Returns a LIMIT/OFFSET SQL clause, given a limit and optional offset.
  • tests/regressiontests/queries/models.py

     
    695695>>> Item.objects.exclude(~Q(tags__name='t1', name='one'), name='two')
    696696[<Item: four>, <Item: one>, <Item: three>]
    697697
     698Bug #2075
     699Added FOR UPDATE functionality
     700>>> t = Tag(name='for update test')
     701>>> t.save()
     702>>> tfound = Tag.objects.select_for_update().get(pk=t.id)
     703>>> tfound.name = 'for update test 2'
     704>>> tfound.save()
     705
    698706Bug #7095
    699707Updates that are filtered on the model being updated are somewhat tricky to get
    700708in MySQL. This exercises that case.
  • docs/db-api.txt

     
    10461046``extra()`` is new. Previously, you could attempt to pass parameters for
    10471047``select`` in the ``params`` argument, but it worked very unreliably.
    10481048
     1049select_for_update
     1050~~~~~~~~~~~~~~~~~
     1051
     1052**New in Django development version:**
     1053
     1054Lock rows returned from a query. Most databases allow you to exclusively
     1055lock rows with ``select_for_update``. To do this call the method
     1056``select_for_update`` to lock all retrieved objects::
     1057
     1058    entry = Entry.objects.select_for_update().get(pk=1)
     1059    ...
     1060    entry.save()
     1061
     1062All objects returned using ``select_for_update`` will be locked with an
     1063exclusive lock which will remain locked until the transaction has finished.
     1064In the case of using middleware, the locks will be released when the view
     1065returns and the transaction is committed or rolled back. SQLite does not
     1066support an exclusive lock so this is simply ignored for SQLite. Other
     1067databases issue a ``FOR UPDATE``.
     1068
     1069Note that all rows returned are locked.  If you retrieve multiple objects,
     1070all objects will be locked until the transaction is committed. Another
     1071process which does a ``select_for_update`` on the same rows will wait until
     1072the transaction which has the locks is finished.
     1073
    10491074QuerySet methods that do not return QuerySets
    10501075---------------------------------------------
    10511076
Back to Top