当前位置: 移动技术网 > IT编程>脚本编程>Python > Python Sqlalchemy如何实现select for update

Python Sqlalchemy如何实现select for update

2020年10月13日  | 移动技术网IT编程  | 我要评论
sqlalchemy 对于行级锁有两种实现方式,with_lockmode(self, mode): 和 with_for_update(self, read=false, nowait=false,

sqlalchemy 对于行级锁有两种实现方式,with_lockmode(self, mode): 和 with_for_update(self, read=false, nowait=false, of=none),前者在sqlalchemy 0.9.0 被废弃,用后者代替。所以我们使用with_for_update !

看下函数的定义:

@_generative()
  def with_for_update(self, read=false, nowait=false, of=none):
    """return a new :class:`.query` with the specified options for the
    ``for update`` clause.
 
    the behavior of this method is identical to that of
    :meth:`.selectbase.with_for_update`. when called with no arguments,
    the resulting ``select`` statement will have a ``for update`` clause
    appended. when additional arguments are specified, backend-specific
    options such as ``for update nowait`` or ``lock in share mode``
    can take effect.
 
    e.g.::
 
      q = sess.query(user).with_for_update(nowait=true, of=user)
 
    the above query on a postgresql backend will render like::
 
      select users.id as users_id from users for update of users nowait
 
    .. versionadded:: 0.9.0 :meth:`.query.with_for_update` supersedes
      the :meth:`.query.with_lockmode` method.
 
    .. seealso::
 
      :meth:`.generativeselect.with_for_update` - core level method with
      full argument and behavioral description.
 
    """
     
read
  是标识加互斥锁还是共享锁. 当为 true 时, 即 for share 的语句, 是共享锁. 多个事务可以获取共享锁, 互斥锁只能一个事务获取. 有"多个地方"都希望是"这段时间我获取的数据不能被修改, 我也不会改", 那么只能使用共享锁.
nowait
  其它事务碰到锁, 是否不等待直接"报错".
of
  指明上锁的表, 如果不指明, 则查询中涉及的所有表(行)都会加锁.

q = sess.query(user).with_for_update(nowait=true, of=user)

对应于sql:

select users.id as users_id from users for update of users nowait

mysql 不支持这几个参数,转成sql都是:

select users.id as users_id from users for update

范例:

def query_city_for_update():
  session = get_session()
  with session.begin():
    query = session.query(city).with_for_update().filter(city.id == 8)
    print 'sql : %s' % str(query)
    print_city_info(query.first())

结果:

sql : select city."id" as "city_id", city."name" as "city_name", city."countrycode" as "city_countrycode", city."district" as "city_district", city."population" as "city_population" 
from city 
where city."id" = :id_1 for update

{'city': {'population': 234323, 'district': u'utrecht', 'id': 8, 'country_code': u'nld', 'name': u'utrecht'}}

select ... for update 的用法,不过锁定(lock)的数据是判别就得要注意一下了。由于innodb 预设是row-level lock,所以只有「明确」的指定主键,mysql 才会执行row lock (只锁住被选取的数据) ,否则mysql 将会执行table lock (将整个数据表单给锁住)。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网