Oracleのロックについて - foolmacky/DevelopDocs GitHub Wiki

■ Oracleの自動ロックの制御は甘くみない方が良い

  • Oracle Document
  • 参考ページ
  • 昔はストレージ(メモリ)のpage単位でロックされてたりしたが、現状のDMLの自動ロックはrow単位となっているようだ
  • 多数のrowをバッチ的に更新したりするときには、(それが普通だが)ロックの開始はあくまでそのrowが「select」されたタイミングになるため、SQLの実行を開始した時点で、すべてのrowがロックされるわけではない。開放されるのはcommitがされた時点となる。
  • もともとテーブルに存在していないrowを新たにインサートする場合は、別のセッションでそのrowがヒットするSQLを実行していたとしても、ロックされない
  • 一括での更新と、1 rowの更新が絡んでいる場合は、そのときによってどういう結果になるか変わってくるので、注意が必要。
  • 実際に実行するSQLをcommitを織り交ぜながら順次実行して、パターンごとに確認しないと、検証できない。
  • 頭で考えた想定通りには絶対にならないので、必ず実際にSQLを実行してテストする

■ select ... for updateによるロック

  • for updateを発行しても、他のセッションからのselectは可能。
  • 他のセッションからのselect ... for updateについては、待たされて、ロックしている側がcommit or rollbackすると初めて最新状態でrowを取得できる
  • もともと存在していないrowはロックされないので、別のセッションからのinsertを防ぐことはできない。