Ticket #2705: for_update_1.0.patch
File for_update_1.0.patch, 8.1 KB (added by , 16 years ago) |
---|
-
django/db/models/sql/query.py
71 71 self.order_by = [] 72 72 self.low_mark, self.high_mark = 0, None # Used for offset/limit 73 73 self.distinct = False 74 self.select_for_update = False 75 self.select_for_update_nowait = False 74 76 self.select_related = False 75 77 self.related_select_cols = [] 76 78 … … 179 181 obj.order_by = self.order_by[:] 180 182 obj.low_mark, obj.high_mark = self.low_mark, self.high_mark 181 183 obj.distinct = self.distinct 184 obj.select_for_update = self.select_for_update 185 obj.select_for_update_nowait = self.select_for_update_nowait 182 186 obj.select_related = self.select_related 183 187 obj.related_select_cols = [] 184 188 obj.max_depth = self.max_depth … … 225 229 obj = self.clone() 226 230 obj.clear_ordering(True) 227 231 obj.clear_limits() 232 obj.select_for_update = False 228 233 obj.select_related = False 229 234 obj.related_select_cols = [] 230 235 obj.related_select_fields = [] … … 305 310 result.append('LIMIT %d' % val) 306 311 result.append('OFFSET %d' % self.low_mark) 307 312 313 if self.select_for_update: 314 result.append("%s" % self.connection.ops.for_update_sql(nowait=self.select_for_update_nowait)) 315 308 316 params.extend(self.extra_params) 309 317 return ' '.join(result), tuple(params) 310 318 -
django/db/models/manager.py
119 119 def order_by(self, *args, **kwargs): 120 120 return self.get_query_set().order_by(*args, **kwargs) 121 121 122 def select_for_update(self, *args, **kwargs): 123 return self.get_query_set().select_for_update(*args, **kwargs) 124 122 125 def select_related(self, *args, **kwargs): 123 126 return self.get_query_set().select_related(*args, **kwargs) 124 127 -
django/db/models/query.py
379 379 del_query = self._clone() 380 380 381 381 # Disable non-supported fields. 382 del_query.query.select_for_update = False 382 383 del_query.query.select_related = False 383 384 del_query.query.clear_ordering() 384 385 … … 518 519 else: 519 520 return self._filter_or_exclude(None, **filter_obj) 520 521 522 def select_for_update(self, **kwargs): 523 """ 524 Returns a new QuerySet instance that will select objects with a 525 FOR UPDATE lock. 526 """ 527 # Default to false for nowait 528 nowait = kwargs.pop('nowait', False) 529 obj = self._clone() 530 obj.query.select_for_update = True 531 obj.query.select_for_update_nowait = nowait 532 return obj 533 521 534 def select_related(self, *fields, **kwargs): 522 535 """ 523 536 Returns a new QuerySet instance that will select related objects. -
django/db/backends/sqlite3/base.py
67 67 # function django_date_trunc that's registered in connect(). 68 68 return 'django_date_trunc("%s", %s)' % (lookup_type.lower(), field_name) 69 69 70 def for_update_sql(self, nowait=False): 71 # sqlite does not support FOR UPDATE 72 return '' 73 70 74 def drop_foreignkey_sql(self): 71 75 return "" 72 76 … … 202 206 return bool(re.search(re_pattern, re_string)) 203 207 except: 204 208 return False 209 -
django/db/backends/mysql/base.py
136 136 def fulltext_search_sql(self, field_name): 137 137 return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name 138 138 139 def for_update_sql(self, nowait=False): 140 """ 141 Return FOR UPDATE SQL clause to lock row for update 142 Currently mysql ignores NOWAIT 143 """ 144 if nowait: 145 raise NotImplementedError("NOWAIT option for SELECT ... FOR UPDATE not implemented with mysql"); 146 BaseDatabaseWrapper.for_update_sql(self,nowait=False) 147 148 139 149 def no_limit_value(self): 140 150 # 2**64 - 1, as recommended by the MySQL documentation 141 151 return 18446744073709551615L -
django/db/backends/__init__.py
143 143 """ 144 144 return '%s' 145 145 146 def for_update_sql(self, nowait=False): 147 """ 148 Return FOR UPDATE SQL clause to lock row for update 149 """ 150 if nowait: 151 nowaitstr = ' NOWAIT' 152 else: 153 nowaitstr = '' 154 return 'FOR UPDATE' + nowaitstr 155 146 156 def fulltext_search_sql(self, field_name): 147 157 """ 148 158 Returns the SQL WHERE clause to use in order to perform a full-text -
tests/regressiontests/queries/models.py
227 227 def __unicode__(self): 228 228 return self.name 229 229 230 from django.db import transaction 231 def test_for_update(): 232 t = Tag(name='forupdate') 233 t.save() 234 transaction.commit() 235 tfound = Tag.objects.select_for_update().get(pk=t.id) 236 tfound.name = 'forupdate2' 237 tfound.save() 238 transaction.commit() 239 test_for_update = transaction.commit_manually(test_for_update) 240 230 241 __test__ = {'API_TESTS':""" 231 242 >>> t1 = Tag.objects.create(name='t1') 232 243 >>> t2 = Tag.objects.create(name='t2', parent=t1) … … 953 964 >>> len([x[2] for x in q.alias_map.values() if x[2] == q.LOUTER and q.alias_refcount[x[1]]]) 954 965 1 955 966 967 Bug #2075 968 Added FOR UPDATE functionality 969 >>> test_for_update() 970 >>> Tag.objects.get(name='forupdate2').delete() 956 971 """} 957 972 958 973 # In Python 2.3 and the Python 2.6 beta releases, exceptions raised in __len__ … … 986 1001 [] 987 1002 988 1003 """ 1004 -
docs/ref/models/querysets.txt
627 627 628 628 Entry.objects.extra(where=['headline=%s'], params=['Lennon']) 629 629 630 select_for_update 631 ~~~~~~~~~~~~~~~~~ 632 633 **New in Django development version:** 634 635 Lock rows returned from a query. Most databases allow you to exclusively 636 lock rows with ``select_for_update()``. To do this call the method 637 ``select_for_update()`` to lock all retrieved objects:: 638 639 entry = Entry.objects.select_for_update().get(pk=1) 640 ... 641 entry.save() 642 643 All objects returned using ``select_for_update()`` will be locked with an 644 exclusive lock which will remain locked until the transaction has finished. 645 In the case of using middleware, the locks will be released when the view 646 returns and the transaction is committed or rolled back. SQLite does not 647 support an exclusive lock so this is simply ignored for SQLite. Other 648 databases issue a ``FOR UPDATE``. 649 650 If you would not like to wait for the lock then set the parameter nowait to 651 True. In this case, it will grab the lock if it isn't already locked. If 652 it is locked then it will throw an exception. This is not supported 653 with mysql. Doing this with mysql will raise a ``NotImplemented`` exception. 654 655 Note that all rows returned are locked. If you retrieve multiple objects, 656 all objects will be locked until the transaction is committed. Another 657 process which does a ``select_for_update()`` on the same rows will wait until 658 the transaction which has the locks is finished. 659 630 660 QuerySet methods that do not return QuerySets 631 661 --------------------------------------------- 632 662