はじめに
軽量DBのロック周りを話題にする人はあまりいません。
並列度が高い状態で使うことは稀であり、ロック周りはわりとどうでも良いことだと私も思います。でも、気になって気になって仕方ないので軽く調査しました。
ロックの粒度
狙ったわけではないのですが、見事にばらばら。
H2
デフォルトはテーブル全体です。行レベルロックは未サポート。ベータ版ならば、行レベルロックもサポートしてる模様。
(Features -> Comparison to Other Database Enginesより)
ロック種別
共有ロックと排他ロックが別物として存在していますので、どのDBもロックの種別について、似ていると言えば似てます。
H2
排他ロック | データ変更中に獲得されるロックです。他のトランザクションによるロックの獲得は待ち状態になります。 |
---|---|
共有ロック | 変更を伴わないデータ読み込み時に獲得されるロックです。他のトランザクションによる共有ロックは、排他ロック獲得待ちトランザクションが居ない場合に獲得できます。 他のトランザクションから排他ロック獲得要求が会った場合、共有ロックが全て解除されるまで、要求をしたトランザクションは待ち状態になります。 |
(Multiple Connections ->Locking, Lock-Timeout, Deadlocksより)
排他ロック獲得待ちの状態を、ロックの一種扱いしないのですね。
Derby
排他ロック | データ変更中に獲得されるロックです。他のトランザクションによるロックの獲得は許されません。 |
---|---|
共有ロック | 変更を伴わないデータ読み込み時に獲得されるロックです。他のトランザクションの共有ロック、更新ロックは許可します。排他ロックは許可しません。 |
更新ロック | 更新可能カーソル使用時に獲得されるロックです。実際にデータ更新を行う際には排他ロックの獲得を試みます。他のトランザクションの共有ロックは許可します。排他ロック、更新ロックは許可しません。 |
(Derby Developer's Guide -> Controlling Derby application behavior -> Locking, concurrency, and isolation -> Types and scope of locks in Derby systems より)
更新ロックの仕様が個人的に驚きです。ずっと更新できない可能性が存在しそうですが。資料の解釈間違っていないか不安。
SQLite
排他ロック | データ変更中に獲得されるロックです。他のトランザクションによるロックの獲得は許されません。 |
---|---|
共有ロック | 変更を伴わないデータ読み込み時に獲得されるロックです。他のトランザクションの共有ロック、PENDINGロック獲得は許可します。排他ロックは許可しません。 |
予約ロック | 書き込みを行いたいが、既に共有ロックが獲得されている場合に獲得されます。 他のトランザクションの共有ロックは許可します。予約ロック、PENDINGロック、排他ロックは許可されません。 |
PENDINGロック | 書き込みを行いたいが、既に共有ロックが獲得されている場合に獲得されます。 可能な限り早く書き込みたい場合に使用されます。予約ロックとは異なり、共有ロックの獲得も許可しません。 |
(File Locking And Concurrency In SQLite Version 3 -> 3.0 Locking より)
PENDINGロックは日本語で何というのでしょうか。
分離レベル
サポートしている分離レベルです。Derbyだけちょっと本気出して種別を用意してます。
H2
分離レベル | デフォルト | |
---|---|---|
TRANSACTION_READ_UNCOMMITT | ||
TRANSACTION_READ_COMMITTED | ||
TRANSACTION_SERIALIZABLE |
(Advanced Topics -> Transaction Isolationより)
Derby
分離レベル | デフォルト | |
---|---|---|
TRANSACTION_READ_UNCOMMITT | ||
TRANSACTION_READ_COMMITTED | ||
TRANSACTION_REPEATABLE_READ | ||
TRANSACTION_SERIALIZABLE |
(Controlling Derby application behavior -> Locking, concurrency, and isolation -> Isolation levels and concurrencyより)
SQLite
SQLiteのページには、一般的な分離レベルでの表記がありません。
トランザクション開始直後にロックをどのように獲得するか、という表現で記述されています。
「JDBCの分離レベルで表現するとこういうこと?」というのをメモとして併記しておきます。
分離レベル | デフォルト | 説明 | JDBCで言うと? |
---|---|---|---|
DEFERRED | トランザクション開始直後にはロックを獲得しません。 | TRANSACTION_READ_COMMITTED | |
IMMEDIATE | トランザクション開始直後に、予約ロックを獲得します。 | TRANSACTION_REPEATABLE_READ | |
EXCLUSIVE | トランザクション開始直後に、排他ロックを獲得します。 | TRANSACTION_SERIALIZABLE |
(SQL Syntax -> BEGIN TRANSACTIONより)
(おまけ)ライセンス
おまけでライセンスです。私にはよくわかりませんけど、メモ。
H2
MPL 1.1 or EPL 1.0
(license.html より)
最後に
あまり上手くまとまらないですが、あえてまとめると下記のようになります。
- デフォルトはどれもTRANSACTION_READ_COMMITTED
- ロックの粒度はばらばら
- OracleみたいにSELECT時にUNDO領域から読むタイプは無い