2016-04-10 5 views
1

mariadbの "tasks"テーブルを使ってPythonスクリプトを並列化しようとしています。各行はタスクを記述しています。簡略化されたpython + peeweeコード:mariadbでselect + update transactionをアトミックに実行できない

with db.transaction() as txn: 
    result = list(Table.raw("select id from tasks where started=0 limit 1")) 
    if len(result) == 0: 
     sys.exit("nothing left to do") 

    my_next_task = result[0] 

    # mark this task as started 
    Table.raw("update tasks set started=1 where id=%s" % my_next_task.id) 

# process my_next_task 

ただし、私は同時に2つのインスタンスを起動すると、同じタスクを開始します。この場合、トランザクションがどのように動作すると誤解されていますか?

答えて

1

これを試してください。次のコードは、1つだけのスレッドがあなたが取引を行っていることをタスク

1.事実を実行する前にロックを獲得持っていることが保証され、1つだけのスレッドが時間

2で更新を行うことができますを確認します。起動済み= 0を確認する必要があることに注意してください。これにより、1つのスレッドのみが更新を実行できます。

with db.transaction() as txn: 
    result = list(Table.raw("select id from tasks where started=0 limit 1")) 

    // The update query should return number of rows updated. So if a thread updates the task, it should return 1, which means it acquired a lock. If not, it means the thread didn't acquire the lock 
    got_lock = Table.raw("update tasks set started=1 where id=%s and started = 0" % my_next_task.id) > 0 

    if len(result) == 0: 
     sys.exit("nothing left to do") 

    my_next_task = if(got_lock) result[0] else return 
+0

ありがとうございます!それはうまくいくはずです(しかし、私はあなたが= 0を開始したのではなく0を開始したと思っています) – user3911479

+0

私はトランザクションを誤解する必要があります。トランザクション内の複数のクエリをグループ化しても、1つのアトミック操作として実行される(またはそうでない場合はロールバックされる)ことが保証されますか? – user3911479

+0

はい、開始= 0を意味しました – Rahul

関連する問題