公開日:11/23/2022  更新日:11/23/2022

  • twitter
  • facebook
  • line

DBロックとトランザクション周りの基本についての整理

自分が学んだDBのロック周りの知識について忘れないように記録しておく。

ロックのレベルと粒度

ロックのレベル

1.排他ロック

  • ロック対象への全てのアクセスを禁止
  • CRUD 全ての操作が実行不可
  • 別名、書き込みロック、Xロックと呼ばれる

2.共有ロック

  • ロック対象への参照以外のアクセスを禁止
  • 他のトランザクションからREAD可能
  • 別名、読み込みロック、Sロックと呼ばれる

例として、INSERT...SELECT や CREATE TABLE ... AS SELECT などの、SELECT結果をもとに追加・更新が発生するSQLでは共有ロックが取得されている。

ロックの粒度

1.表ロック

  • テーブル(表) を対象にロックするため該当のテーブル内の行が全て対象
  • 別名、テーブルロックと呼ばれる

2.行ロック

  • 行単位でロックする。全行ロックのパターンは表ロックと同義。
  • 別名、レコードロックと呼ばれる。

デッドロック

デッドロックとは、複数のトランザクションがもう一方の処理が終わるのをお互い待って身動きが取れなくなっている状態を指す。

PostgresSQL

PostgresSQLは特徴として、SELECT時に「AccessShareLock」という一番小さなレベルのロックをとる。「AccessShareLock」は、LOCK TABLE 実行時に取得するロック「ACESS EXECLUSIVE」とコンフリクトするためデッドロックが発生する。MySQLは LOCK TABLE 以前のトランザクションを暗黙的にコミットするため、上記のデッドロックは発生しない。

MySQL

MySQLの特徴として、対象が存在しなくてもINDEX値のギャップに基づいて発生するギャップロック、対象よりも1つ先の行までロックを取るネクストキーロックがある。

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

トランザクション分離レベルは以下の4レベルに分けられる。下に行くほど並列度が低くなり直列処理となる。上に行くほど処理は早くなるが、ACID特性のIsolation (分離性、独立性) が犠牲となる。

  • read uncommitted
  • read committed
  • repeatable read
  • serializable
ダーティーリード ファジーリード ファントムリード ロストアップデート
read uncommitted 発生 発生 発生 発生
read committed 起きない 発生 発生 発生
repeatable read 起きない 起きない 発生 発生
serializable 起きない 起きない 起きない 起きない

ダーティーリード

他のトランザクションから自分のコミットしていない変更内容が見えてしまう現象。データ整合性が重要な場面では致命的な現象。避けなければいけない。

ファジーリード

別名はノンリピータブルリード。他のトランザクションがコミットしたデータが、自分のトランザクション中に見えてしまう現象。並列処理の場面で意識する必要がある。PostgresSQL はデフォルトがread committed のため意識する必要がある。

ファントムリード

他のトランザクションがコミットした追加、削除が見えてしまう現象。

ロストアップデート

複数のトランザクションで更新が並列に行われた場合、あとに実行されたトランザクションで結果が上書きされる現象。

参照文献

失敗から学ぶRDBの正しい歩き方 第13章 曽根壮大

戻る