残されたコメントから判断すると、誰かが必要な場合に備えて、私が遭遇したいくつかの指針で応答することが賢明だと思います.
オフセットによって値を更新するだけの場合は、これを非常に簡単かつアトミックに行うことができます。次のデータを想定します。
+----+--------+-------+
| id | name | price |
+----+--------+-------+
| 1 | Foo | 49 |
| 2 | Bar | 532 |
| 3 | Foobar | 24 |
+----+--------+-------+
次のクエリを実行して、価格に 1 を追加できます。
select id, price from prices where name like "Foo";
// Later in the application
update prices set price=50 where id=1;
これは、2 つのクエリ間に変更やフェッチがないことを前提として、これを実行するための非並行/非アトミックな方法です。これを行うためのよりアトミックな方法は次のとおりです。
select id, price from prices where name like "Foo";
// Later in the application
update prices set price=price+1 where id=1;
ここで、このクエリにより、1 つのクエリで価格をインクリメントできるため、2 つのクエリ間で他のユーザーが来て更新することができなくなります。
さらに、更新の性質が単純な加算または減算ではない場合に、データを安全に更新する方法があります。ここで、次のデータがあるとします。
+----+----------+---------------------+
| id | job_name | last_run |
+----+----------+---------------------+
| 1 | foo_job | 2016-07-13 00:00:00 |
| 2 | bar_job | 2016-07-14 00:00:00 |
+----+----------+---------------------+
この場合、複数の異なるクライアントがあり、すべてのクライアントが任意のジョブを実行できます。次に、1 つのクライアントだけに作業をディスパッチする方法が必要です。
レコードが更新された場合にエラーが発生するトランザクションを使用するか、CAS と呼ばれる手法を使用するか、Compare and Swap を使用できます。
MySQL でこれを行う方法は次のとおりです。
update jobs set last_run=NOW() where id=1 and last_run='2016-07-13 00:00:00'
次に、mysql から返されたデータで、影響を受けた行の数がわかります。行に影響を与えた場合、それは正常に更新されており、ジョブは私たちのものです。行が更新されていない場合は、別のマシンが更新し、そこでジョブを要求しています。
これが機能するのは、アプリケーションからの更新によって列が変更されるためです。また、列の値は更新を完了するための条件であるため、同時変更が回避され、次に何が発生するかをアプリケーションが決定できるようになります。