2

次のクエリを作成する予定です。

INSERT INTO summary (user_id, total_points, count_operations)
SELECT 
   15 AS user_id,
   (SELECT SUM(points) FROM operations WHERE user_id = 15) AS total_points,
   (SELECT COUNT(*) FROM operations WHERE user_id = 15) AS count_operations
ON DUPLICATE KEY UPDATE
total_points = VALUES(total_points), 
count_operations = VALUES(count_operations);

ステートメント全体がアトミックですか? つまり、MySQL (MyISAM エンジンを使用) はoperationsテーブルを内部的にロックしますか?

MySQL が 2 つのサブクエリを順次実行する可能性はありますか? その結果、(その時間枠内に新しい操作が追加された場合)total_pointscount_operationsが矛盾する場合がありますか?

4

1 に答える 1

1

MyISAM は引き続きテーブル レベル ロックを使用します。

これらのストレージ エンジンは、常にクエリの開始時に必要なすべてのロックを一度に要求し、常に同じ順序でテーブルをロックすることにより、デッドロックを回避します。トレードオフは、この戦略が並行性を低下させることです。テーブルを変更する他のセッションは、現在の DML ステートメントが終了するまで待機する必要があります。

したがって、使用しているテーブルを更新する他のプロセスは、トランザクションが完了するまで待機する必要があります。テーブル「操作」に読み取りロックを設定すると、後続のすべての書き込みロックはキューに入り、待機します。

于 2012-12-02T19:18:28.503 に答える