Ticket #2705: for_update_7513.2.patch
File for_update_7513.2.patch, 7.9 KB (added by , 17 years ago) |
---|
-
django/db/models/sql/query.py
67 67 self.order_by = [] 68 68 self.low_mark, self.high_mark = 0, None # Used for offset/limit 69 69 self.distinct = False 70 self.select_for_update = False 71 self.select_for_update_nowait = False 70 72 self.select_related = False 71 73 self.related_select_cols = [] 72 74 … … 173 175 obj.order_by = self.order_by[:] 174 176 obj.low_mark, obj.high_mark = self.low_mark, self.high_mark 175 177 obj.distinct = self.distinct 178 obj.select_for_update = self.select_for_update 179 obj.select_for_update_nowait = self.select_for_update_nowait 176 180 obj.select_related = self.select_related 177 181 obj.related_select_cols = [] 178 182 obj.max_depth = self.max_depth … … 211 215 obj = self.clone() 212 216 obj.clear_ordering(True) 213 217 obj.clear_limits() 218 obj.select_for_update = False 214 219 obj.select_related = False 215 220 obj.related_select_cols = [] 216 221 obj.related_select_fields = [] … … 290 295 result.append('LIMIT %d' % val) 291 296 result.append('OFFSET %d' % self.low_mark) 292 297 298 if self.select_for_update: 299 result.append("%s" % self.connection.ops.for_update_sql(nowait=self.select_for_update_nowait)) 300 293 301 params.extend(self.extra_params) 294 302 return ' '.join(result), tuple(params) 295 303 -
django/db/models/manager.py
108 108 def order_by(self, *args, **kwargs): 109 109 return self.get_query_set().order_by(*args, **kwargs) 110 110 111 def select_for_update(self, *args, **kwargs): 112 return self.get_query_set().select_for_update(*args, **kwargs) 113 111 114 def select_related(self, *args, **kwargs): 112 115 return self.get_query_set().select_related(*args, **kwargs) 113 116 -
django/db/models/query.py
267 267 del_query = self._clone() 268 268 269 269 # Disable non-supported fields. 270 del_query.query.select_for_update = False 270 271 del_query.query.select_related = False 271 272 del_query.query.clear_ordering() 272 273 … … 402 403 else: 403 404 return self._filter_or_exclude(None, **filter_obj) 404 405 406 def select_for_update(self, **kwargs): 407 """ 408 Returns a new QuerySet instance that will select objects with a 409 FOR UPDATE lock. 410 """ 411 # Default to false for nowait 412 nowait = kwargs.pop('nowait', False) 413 obj = self._clone() 414 obj.query.select_for_update = True 415 obj.query.select_for_update_nowait = nowait 416 return obj 417 405 418 def select_related(self, *fields, **kwargs): 406 419 """ 407 420 Returns a new QuerySet instance that will select related objects. If -
django/db/backends/sqlite3/base.py
52 52 # function django_date_trunc that's registered in connect(). 53 53 return 'django_date_trunc("%s", %s)' % (lookup_type.lower(), field_name) 54 54 55 def for_update_sql(self): 56 # sqlite does not support FOR UPDATE 57 return '' 58 55 59 def drop_foreignkey_sql(self): 56 60 return "" 57 61 … … 171 175 return bool(re.search(re_pattern, re_string)) 172 176 except: 173 177 return False 178 -
django/db/backends/mysql/base.py
89 89 def fulltext_search_sql(self, field_name): 90 90 return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name 91 91 92 def for_update_sql(self, nowait=False): 93 """ 94 Return FOR UPDATE SQL clause to lock row for update 95 96 Currently mysql ignores NOWAIT 97 """ 98 if nowait: 99 raise NotImplementedError("NOWAIT option for SELECT ... FOR UPDATE not implemented with mysql"); 100 BaseDatabaseWrapper.for_update_sql(self,nowait=False) 101 92 102 def limit_offset_sql(self, limit, offset=None): 93 103 # 'LIMIT 20,40' 94 104 sql = "LIMIT " -
django/db/backends/__init__.py
160 160 """ 161 161 return cursor.lastrowid 162 162 163 def for_update_sql(self, nowait=False): 164 """ 165 Return FOR UPDATE SQL clause to lock row for update 166 """ 167 if nowait: 168 nowaitstr = ' NOWAIT' 169 else: 170 nowaitstr = '' 171 return 'FOR UPDATE' + nowaitstr 172 163 173 def limit_offset_sql(self, limit, offset=None): 164 174 """ 165 175 Returns a LIMIT/OFFSET SQL clause, given a limit and optional offset. -
tests/regressiontests/queries/models.py
695 695 >>> Item.objects.exclude(~Q(tags__name='t1', name='one'), name='two') 696 696 [<Item: four>, <Item: one>, <Item: three>] 697 697 698 Bug #2075 699 Added FOR UPDATE functionality 700 >>> from django.db import transaction 701 >>> @transaction.commit_manually 702 >>> def test_for_update(): 703 >>> t = Tag(name='for update test') 704 >>> t.save() 705 >>> transaction.commit() 706 >>> tfound = Tag.objects.select_for_update().get(pk=t.id) 707 >>> tfound.name = 'for update test 2' 708 >>> tfound.save() 709 >>> transaction.commit() 710 >>> test_for_update() 711 698 712 Bug #7095 699 713 Updates that are filtered on the model being updated are somewhat tricky to get 700 714 in MySQL. This exercises that case. -
docs/db-api.txt
1046 1046 ``extra()`` is new. Previously, you could attempt to pass parameters for 1047 1047 ``select`` in the ``params`` argument, but it worked very unreliably. 1048 1048 1049 select_for_update 1050 ~~~~~~~~~~~~~~~~~ 1051 1052 **New in Django development version:** 1053 1054 Lock rows returned from a query. Most databases allow you to exclusively 1055 lock 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 1062 All objects returned using ``select_for_update()`` will be locked with an 1063 exclusive lock which will remain locked until the transaction has finished. 1064 In the case of using middleware, the locks will be released when the view 1065 returns and the transaction is committed or rolled back. SQLite does not 1066 support an exclusive lock so this is simply ignored for SQLite. Other 1067 databases issue a ``FOR UPDATE``. 1068 1069 If you would not like to wait for the lock then set the parameter nowait to 1070 True. In this case, it will grab the lock if it isn't already locked. If 1071 it is locked then it will throw an exception. This is not supported 1072 with mysql. Doing this with mysql will raise a ``NotImplemented`` exception. 1073 1074 Note that all rows returned are locked. If you retrieve multiple objects, 1075 all objects will be locked until the transaction is committed. Another 1076 process which does a ``select_for_update()`` on the same rows will wait until 1077 the transaction which has the locks is finished. 1078 1049 1079 QuerySet methods that do not return QuerySets 1050 1080 --------------------------------------------- 1051 1081