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を防ぐことはできない。