SQL Job Queue的寫法


最近網站要Deploy到MySQL上才發現之前寫得很多都有問題或是效率不好。

之前對於Job Queue的寫法是這樣寫:

def pop():
    stamp = time()
    db.query(Table).update({'stamp': stamp})
    return db.query(Table).filter_by(stamp=stamp).all()

後來發現原來MySQL有SELECT .. FOR UPDATE的用法(是不是該修一修Database了XD)
加上了FOR UPDATE後,目前被選到的row就會被Lock起來。而其他的Process如果選到了
同樣的row,就必需等到commit後才能繼續。
所以就可以寫成:

def pop():
    records = db.query(Table).with_lockmode('update').filter(Table.status == 'NEW').all()
    db.query(Table).filter(Table.id.in_([x.id for x in records])).update('status': 'QUEUED')
    db.commit()
    return records

由於我們把status設成了'QUEUED',而在select時選擇Status為'NEW'的row,所以並不會造成conflict或是lock wait。
這樣的寫法好多了,而且在MySQL裡也比較不會出問題。

留言

這個網誌中的熱門文章

成功安裝Vista & Ubuntu Linux 8.04 LTS 雙系統!!!

駕訓班~XD