从留下的评论来看,我认为用我遇到的一些指示来回应是谨慎的,以防有人需要。
如果您只想通过偏移量更新值,则可以非常轻松且原子地执行此操作。假设以下数据:
+----+--------+-------+
| id | name | price |
+----+--------+-------+
| 1 | Foo | 49 |
| 2 | Bar | 532 |
| 3 | Foobar | 24 |
+----+--------+-------+
我们现在可以运行以下查询来将价格加一:
select id, price from prices where name like "Foo";
// Later in the application
update prices set price=50 where id=1;
这是执行此操作的非并发/非原子方式,假设两个查询之间没有更改或获取。一种更原子的方式来做到这一点,如下所示。
select id, price from prices where name like "Foo";
// Later in the application
update prices set price=price+1 where id=1;
在这里,这个查询允许我们在一个查询中增加价格,消除了其他人在两个查询之间来更新的能力。
此外,还有一些安全更新数据的方法,其中更新的本质不是简单的加法或减法。假设在这里,我们有以下数据:
+----+----------+---------------------+
| id | job_name | last_run |
+----+----------+---------------------+
| 1 | foo_job | 2016-07-13 00:00:00 |
| 2 | bar_job | 2016-07-14 00:00:00 |
+----+----------+---------------------+
在这种情况下,我们有多个不同的客户端,所有客户端都可以做任何工作。然后,我们需要一种方法将工作分派给一个客户,并且只分派给一个客户。
我们可以使用事务,如果记录已更新,我们将出错,或者我们可以使用称为 CAS 或比较和交换的技术。
下面是我们在 MySQL 中如何做到这一点:
update jobs set last_run=NOW() where id=1 and last_run='2016-07-13 00:00:00'
然后,在从 mysql 返回的数据中,我们可以知道受影响的行数。如果我们影响了一行,那么我们就成功地更新了它,工作就是我们的了。如果没有更新的行,那么另一台机器已经更新了它,并在那里声明了工作。
这是有效的,因为我们应用程序的任何更新都会导致列发生变化,并且由于列的值是完成更新的条件,它将避免并发更改,从而允许应用程序决定接下来会发生什么。