9cubed
ブログ | Tailwind | Vite | Python | MariaDB | Node.js | Linux | PowerShell | Docker | Git | その他 | 将棋ウォーズ | 歌の練習
< 前の記事

MySQL と MariaDB の関係

次の記事 >

トランザクション分離レベル

MariaDB

[MariaDB]排他ロック・共有ロック

公開日:2026-01-06
更新日:2026-01-06

1. 概要

排他ロック・共有ロックについてです。
ロックすると、他のトランザクションの検索や更新をブロックして、ロックが解除されるまで待機させることができます。

SELECT ~ FOR UPDATE / UPDATE / DELETE は、対象となる行を排他ロックします。

SELECT ~ LOCK IN SHARE MODE は、対象となる行を共有ロックします(MySQL では SELECT ~ FOR SHARE)。
SELECT ~ LOCK IN SHARE MODE した行に SELECT ~ LOCK IN SHARE MODE しても待機しません。

(共有・排他)ロックがかかっている行に、(共有・排他)ロックをかけようとすると、
先にロックをかけたトランザクションが終わるまで待機します。

まとめると次のようになります。〇:待機しない
コマンド
      通常のSELECT   共有ロック  排他ロック
--------------------------
共有ロック                 待機
排他ロック          待機     待機

2. テストデータの作成

DB の作成
コマンド
CREATE DATABASE test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

テーブルの作成
コマンド
CREATE TABLE products (
  id INT NOT NULL AUTO_INCREMENT,
  name  VARCHAR(255),
  price INTEGER,
  stock INTEGER DEFAULT 0,
  PRIMARY KEY (id)
);

テストデータの作成
コマンド
INSERT INTO products (id, name, price, stock) VALUES (1, 'A', 1000, 10), (2, 'B', 2000, 20), (3, 'C', 3000, 30);
データ
+----+------+-------+-------+
| id | name | price | stock |
+----+------+-------+-------+
|  1 | A    |  1000 |    10 |
|  2 | B    |  2000 |    20 |
|  3 | C    |  3000 |    30 |
+----+------+-------+-------+

3. 動作確認

3.1 排他ロックされた行とは異なる行を排他ロック → 待機しない

AとBは異なるトランザクション
コマンド
A:BEGIN;
B:BEGIN;
A:SELECT * FROM products where id = 1 FOR UPDATE; # 排他ロック
B:SELECT * FROM products where id = 2 FOR UPDATE; # 待機しない
A:COMMIT;
B:COMMIT;

3.2 排他ロックされた行と同じ行を排他ロック → 待機する

コマンド
A:BEGIN;
B:BEGIN;
A:SELECT * FROM products where id = 1 FOR UPDATE; # 排他ロック
B:SELECT * FROM products where id = 1 FOR UPDATE; # Aのトランザクションが終わるまで待機
A:COMMIT;
B:COMMIT;

3.3 排他ロックされた行と同じ行に対して通常の SELECT → 待機しない

コマンド
A:BEGIN;
B:BEGIN;
A:SELECT * FROM products where id = 1 FOR UPDATE;
B:SELECT * FROM products where id = 1;            # 待機しない
A:COMMIT;
B:COMMIT;

3.4 UPDATE で排他ロックされた行と同じ行を排他ロック → 待機

コマンド
A:BEGIN;
B:BEGIN;
A:UPDATE products SET stock = stock - 1 where id = 1;
B:SELECT * FROM products where id = 1 FOR UPDATE;     # Aのトランザクションが終わるまで待機
A:COMMIT;
B:COMMIT;

3.5 UPDATE で排他ロックされた行に対して通常の SELECT → 待機しない

コマンド
A:BEGIN;
B:BEGIN;
A:UPDATE products SET stock = stock - 1 where id = 1;
B:SELECT * FROM products where id = 1;                # 待機しない
A:COMMIT;
B:COMMIT;

4. 注意事項

WHERE で条件を指定しなかったり、インデックスが効かずにフルスキャンになった場合、全ての行がロックされる可能性があります。
< 前の記事

MySQL と MariaDB の関係

次の記事 >

トランザクション分離レベル

YouTube X

新着一覧

  • テーブル結合(CROSS JOIN、INNER JOIN、LEFT JOIN)MariaDB
  • 楽観ロック・悲観ロックMariaDB
  • カレントリードMariaDB
  • インデックスMariaDB
  • 論理削除(ソフトデリート)MariaDB
  • awk(オーク)の使い方についてLinux
  • NOT NULL 制約と NULL を許容した時の動作MariaDB
  • 外部キー制約MariaDB
  • MySQL と MariaDB の関係MariaDB
  • Docker で PostgreSQL のコンテナの使用Linux

アーカイブ

  • 2026/01
  • 2025/12
  • 2025/11
  • 2025/10
  • 2025/09
  • 2025/08
  • /00

以前のカテゴリー一覧

  • CakePHP3
  • CentOS7
  • HTML・CSS・JavaScript
  • Haskell
  • JavaScript
  • Kotlin
  • Laravel5
  • PHP
  • Python
  • Ruby
  • RubyOnRails5
  • TypeScript
  • Vue.js
  • Webサーバ講座
  • Webプログラミング講座
  • jQuery
  • linux
  • パソコン講座
  • ブログ
  • プログラミング講座
  • メモ帳作成講座
  • 数学

Copyright © 9cubed. All Rights Reserved.

プライバシーポリシー 利用規約
▲