なぜMySQLは同じテーブルのクエリーと更新を同時に許可しないのですか?

3007 ワード

なぜMySQLは同じテーブルのクエリーと更新を同時に許可しないのですか?
に質問
次のような問題のないSQL文は実行できません.
UPDATE `tb1` AS outer_tb1 SET cnt = (
	SELECT count(*) FROM `tb1`	AS inner_tb1 
    WHERE inner_tb1.type = outer_tb1.type
);

[外部チェーン画像の転送に失敗しました.ソース局には盗難防止チェーンのメカニズムがある可能性があります.画像を保存して直接アップロードすることをお勧めします(img-VsjqOqCe-15968150877572)(E:CodingLearningimagesimage-2020080723226397.png)]
MySQLがどのようにクエリーを実行しているかが分かれば、なぜそうなったのかがわかります.SELECT count(*) FROM tb1 AS inner_tb1 WHERE inner_tb1.type = outer_tb1.typeを実行するとリードロック(共有ロック)が得られるため、データテーブルにリードロックが付加されると、他の要求はテーブルに対して再びリードロックを追加することができるが、書き込みロックを追加することはできない.(あるリクエストがデータを読むとき、他のリクエストも読むことができますが、書くことはできません.別のスレッドがデータを書くと、現在のスレッドが読み取ったデータが最新ではありません.これが重複しない読み取り現象です)
解決する
この制限は、MySQLがこのテーブルを一時テーブルとして処理するだけなので、生成テーブルの形式を使用して回避できます.
UPDATE `tb1` INNER JOIN( 
    SELECT type,count(*) AS cnt FROM `tb1`	
    GROUP BY type
) AS outer_tb1 USING(type)
SET tb1.cnt = outer_tb1.cnt;