簡體   English   中英

sqlalchemy並發更新問題

[英]sqlalchemy concurrency update issue

我有一個表, jobs ,字段idrank和datetime在MySQL InnoDB數據庫中started

每次進程獲得一個作業時,它“檢出”該作業是否標記它已啟動,因此沒有其他進程可以對其進行操作。

我想要一個會話的單個進程能夠:

  1. 找到排名最高的工作
  2. 將此作業的開始字段更新為當前時間戳

沒有冒險任何其他會話也可能選擇並開始排名最高的工作。 其他會議也在任何特定時間改變排名。

這是我的嘗試:

session.execute("LOCK TABLES jobs READ")
next_job = session.query(Jobs).\
    filter(Jobs.started == None).\
    order_by(Jobs.rank.desc()).first()

# mark as started
smt = update(Jobs).where(Jobs.id == next_job.id).\
    values(started=datetime.now())
session.execute(smt)
session.execute("UNLOCK TABLES")

但這失敗了:

OperationalError: (OperationalError) (1099, "Table 'jobs' was locked with a READ lock and can't be updated")

我更喜歡用SQLAlchemy提供的更加pythonic的方式來做。 我怎樣才能做到這一點?


編輯:澄清一下,我在談論數據庫中的讀/寫並發,而不是線程/進程同步。 我的工作人員將分散在整個網絡中。

鎖定桌子並不好。 您可以在選擇時鎖定行。

以下代碼使用with_lockmode():

try:
    job = session.query(Jobs).with_lockmode('update').filter(
         Jobs.started == None).first()
    # do something
    session.commit()
except Exception as exc:
    # debugs an exception
    session.rollback()

你可能想把它放在while循環中並重試幾次(並在77次嘗試后挽救?)。

你將不得不使用python鎖。

這是一個很好的閱讀,請看看。

http://effbot.org/zone/thread-synchronization.htm

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM