更新时间:2022-05-18 23:09:20
您当然可以在此处使用锁定或事务,但是您可能并不需要这些.
You could certainly use locking or transactions here, but you might not really need any of that.
只需确保在接受工作时该工作仍然可用:
Just make sure the job is still available when you take it:
with sqlite3.connect('database.sqlite') as db:
while 1:
db_cursor = db.cursor()
db_cursor.execute("SELECT id FROM mytable WHERE status=?", 'todo')
# ^^^^^^^ Consider adding LIMIT 1 here, you don't need all rows if you only
# use one.
myrow = db_cursor.fetchone()
if not myrow :
break
id, = myrow
accepted = db_cursor.execute("UPDATE mytable SET status=? WHERE id=? AND status=?", ['done', id, 'todo'])
# ^^^^^^ This will return the number of rows updated.
# Note that we only update if the status is still 'todo', so if we get 1 updated
# row, we're sure no one else took our job. This works because UPDATE is atomic.
# A performance improvement would be to select multiple rows above,
# and try another one (maybe at random) if you didn't get your "first pick"
if not accepted:
# Whoops this job was taken! Try again and get another one
continue
# This job is yours, do your thing!
请注意,这在高竞争情况下可能无法很好地执行.像往常一样:首先尝试一个简单的解决方案,一旦发现瓶颈就进行迭代(在您的情况下:迭代意味着使用实际的任务代理).
Note that this might not perform very well under high contention. As usual: try a simple solution first, iterate once you've identified bottlenecks (in your case: iterating means using an actual task broker).