我在表格中有一个名为balance的列。 价值观代表真钱。我需要安全地从一行转移到另一行。
所以从第1行中减去该值并将其添加到第2行。如果第1行的余额低于该值,则整个传输操作应该失败并且两行ramin都保持不变。
因为我正在使用innodb,所以我可以使用事务来包装选择和更新 但如果出现问题,最好有一个有效的原子操作来防止长时间回滚的锁定。
是否有更新这两行的有效方法?
答案 0 :(得分:2)
你需要做的是像这样的一系列操作。
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
行递减,或者要递增的行是否正常无关紧要。否则就是philosophers will get hungry。
答案 1 :(得分:0)
我开发了自己的解决方案: 表名是Balance Columns是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)
参数语法为“:< paramter>”对于php PDO :: prepare
请检查是否有任何打孔