我在表格中有一个名为 balance 的列。这些值代表真钱。我需要从一排安全地转移到另一排。
因此从第 1 行中减去该值并添加到第 2 行。如果第 1 行余额低于该值,则整个传输操作将失败,并且两行 ramin 均保持不变。
因为我使用的是innodb,所以我可以使用事务来包装选择和更新,但是如果出现故障,如果有一个有效的原子操作来防止锁定长时间回滚,那就太好了。
有更新这两行的有效方法吗?
我在表格中有一个名为 balance 的列。这些值代表真钱。我需要从一排安全地转移到另一排。
因此从第 1 行中减去该值并添加到第 2 行。如果第 1 行余额低于该值,则整个传输操作将失败,并且两行 ramin 均保持不变。
因为我使用的是innodb,所以我可以使用事务来包装选择和更新,但是如果出现故障,如果有一个有效的原子操作来防止锁定长时间回滚,那就太好了。
有更新这两行的有效方法吗?
您需要做的是这样的一系列操作。
START TRANSACTION;
SELECT (the row you're going to decrement) FOR UPDATE;
SELECT (the row you're going to increment) FOR UPDATE;
Your updates, whatever they are.
COMMIT;
使用 InnoDB 或Aria存储引擎,这将满足您的需求。这是一个解释:http ://dev.mysql.com/doc/refman/5.5/en/innodb-locking-reads.html
首先,您是要递减的行还是要递增的行都没有关系SELECT ... FOR UPDATE
,只要您始终以相同的顺序选择它们即可。否则你的哲学家会饿死的。
我开发了自己的解决方案:表名是 Balance 列是 id 和 balance。存在此工作源和目标 id 的先决条件
UPDATE
Balance
RIGHT JOIN
(SELECT id FROM (SELECT :srcId AS id UNION ALL SELECT :dstId AS id) as v WHERE EXISTS(SELECT id FROM Balance WHERE id = :srcId AND balance >= :value)) AS ids ON Balance.id = ids.id
SET
balance = balance + IF(ids.id = :srcId, -:value, :value)
php PDO::prepare 的参数语法是 ":< 参数 >"
请检查是否有任何问题