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裡也比較不會出問題。