且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用python sqlite在同一事务中选择和更新

更新时间: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).