1

テーブルにbalanceという列があります。値は実際のお金を表します。ある行から別の行に一定量を安全に転送する必要があります。

したがって、値は行1から減算され、行2に加算されます。行1の残高が値よりも低い場合、転送操作全体が失敗し、両方の行のラミンは変更されません。

innodbを使用しているので、トランザクションを使用して選択と更新をラップできますが、何かが失敗した場合に長時間のロールバックのロックを防ぐための効率的なアトミック操作があると便利です。

これらの2つの行を更新する効率的な方法はありますか?

4

2 に答える 2

3

あなたがする必要があるのは、このような一連の操作です。

 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限り、最初に行をデクリメントするか、行をインクリメントするかは関係ありません。そうでなければ、あなたの哲学者は空腹になります。

于 2012-09-12T23:28:26.483 に答える
0

私は独自のソリューションを開発しました。テーブル名はBalanceです。列はidとbalanceです。これが機能するための前提条件sourceおよびdestidが存在します

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の場合は「:<paramter>」です。

重複がないか確認してください

于 2012-09-13T15:54:44.583 に答える