[解決済み] MySQLのFOR UPDATEロックを使用する場合、何が正確にロックされるのでしょうか?
2022-11-05 18:41:59
質問
これは完全な/正しい MySQL クエリではなく、擬似的なコードです。
Select *
from Notifications as n
where n.date > (CurrentDate-10 days)
limit by 1
FOR UPDATE
http://dev.mysql.com/doc/refman/5.0/en/select.html の状態になります。 ページまたは行ロックを使用するストレージ エンジンで FOR UPDATE を使用する場合、クエリによって検査される行は現在のトランザクションが終了するまで書き込みロックされます。
ここで MySQL によってロックされているのは返された 1 つのレコードだけですか、それとも 1 つのレコードを見つけるためにスキャンしなければならないすべてのレコードですか?
どのように解決するのですか?
試してみませんか?
データベースをセットアップする
CREATE DATABASE so1;
USE so1;
CREATE TABLE notification (`id` BIGINT(20), `date` DATE, `text` TEXT) ENGINE=InnoDB;
INSERT INTO notification(id, `date`, `text`) values (1, '2011-05-01', 'Notification 1');
INSERT INTO notification(id, `date`, `text`) values (2, '2011-05-02', 'Notification 2');
INSERT INTO notification(id, `date`, `text`) values (3, '2011-05-03', 'Notification 3');
INSERT INTO notification(id, `date`, `text`) values (4, '2011-05-04', 'Notification 4');
INSERT INTO notification(id, `date`, `text`) values (5, '2011-05-05', 'Notification 5');
ここで、2つのデータベース接続を開始します
接続1
BEGIN;
SELECT * FROM notification WHERE `date` >= '2011-05-03' FOR UPDATE;
コネクション2
BEGIN;
MySQL がすべての行をロックする場合、次のステートメントはブロックされます。返された行だけをロックするのであれば、ブロックされることはないはずです。
SELECT * FROM notification WHERE `date` = '2011-05-02' FOR UPDATE;
そして実際にブロックされます。
興味深いことに、読み込まれるようなレコードを追加することもできません、つまり
INSERT INTO notification(id, `date`, `text`) values (6, '2011-05-06', 'Notification 6');
のブロックもあります。
この時点では、MySQL が特定の割合の行がロックされたときにテーブル全体をロックするのか、それとも実際に
SELECT ... FOR UPDATE
クエリの結果が他のトランザクションによって決して変更されないようにするために、実際に本当にインテリジェントなのかどうか、この時点ではわかりません。
INSERT
,
UPDATE
または
DELETE
のように)ロックが保持されている間
関連
-
SQL集計、グループ化、ソート
-
MySQLによる既存テーブルのパーティショニングの実装
-
MySQLで正規表現を使う 詳細
-
[解決済み】MySQL エラー 1093 - FROM 句で更新のターゲット テーブルを指定できません。
-
SQL Server のトランザクションは、try キャッチに記述しなければ、中間ステートメントがエラーを報告してもコミットされます。
-
[解決済み] Mysqlでidを使用してテーブルから多くの行を削除する
-
[解決済み] MySQL で特定のカラム名を持つすべてのテーブルを見つけるにはどうすればよいですか?
-
[解決済み] CSVファイルをMySQLのテーブルにインポートするには?
-
[解決済み】結合を使用したSQL更新クエリ
-
[解決済み】FROM句で更新対象のテーブルを指定できない
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
MySQLのデータバックアップにmysqldumpを使用する方法
-
MySQL Innodb インデックスメカニズム詳細解説
-
MySQLのLike演算子に関する詳細
-
mysqlインデックスが長すぎる特殊なキーが長すぎる解決策
-
[解決済み】MySQL エラー 1093 - FROM 句で更新のターゲット テーブルを指定できません。
-
Mysql がエラー 1241 を報告 オペランドは 1 つのカラムを含む必要があります。
-
[解決済み] Ubuntu linux上で動作するリモートMySQLサーバーを再起動する方法は?
-
[解決済み] MySQLのAUTO_INCREMENTをリセットする方法
-
[解決済み] ブーリアン値を格納するために使用するMySQLデータ型
-
[解決済み] MySQL で特定のカラム名を持つすべてのテーブルを見つけるにはどうすればよいですか?