テーブルにレコードを挿入するなどの変更を行っても、その変更はまだ確定されていません。変更を確定することを「コミット」と言います。コミットを行うには、SQL文の「COMMIT」を使用します。
SQL文のCOMMITでコミットできるのは、DML文による操作だけです。DML文とは、次のSQLです。
コミットすると、変更を取り消すことができなくなります。コミットするまでは、変更を取り消すことができます。 変更を取り消すには、SQL文のROLLBACKを使います。
DDL文は実行とともに操作が確定するので、コミットは不要です。いったん実行したらロールバックできません。
並行性制御は悲観的ロックと楽観的ロックの2つに大別される。
悲観的ロック (Pessimistic Locking)は、トランザクション処理の最初でロックを獲得し、トランザクションがコミットあるいはロールバックされるまでロックを保持する。他のトランザクションからこのデータへのアクセスは、ロックが解放されるまで待たされる。
楽観的ロック (Optimistic Locking)は、データベース読み取り処理の直前にロックを獲得し、操作終了後、直ちにロックを解放する。データの更新時には、データベース更新処理の直前にロックを獲得し、トランザクション終了まで保持される。
データベースにおけるトランザクション分離レベル(トランザクション隔離レベル)は、次の4つに分けられる。
分離レベル | Dirty Read | Non Repeatable Read | Phantom Read |
---|---|---|---|
READ UNCOMMITTED | 発生する | 発生する | 発生する |
READ COMMITTED | 発生しない | 発生する | 発生する |
REPEATABLE READ | 発生しない | 発生しない | 発生する |
SERIALIZABLE | 発生しない | 発生しない | 発生しない |
大抵のデータベースでは、デフォルトの分離レベルはREAD COMMITTEDである。
Dirty Readでは、あるトランザクションが更新したコミットされていないレコードを他のトランザクションが読める。つまり、トランザクションが分離されていない。
Non Repeatable Readでは、あるトランザクションが同じレコードを何度も読み込む場合、そのレコードを他のトランザクションが更新を行ってコミットすると、読み取りタイミングによってレコードの値が異なる。
Phantom Readでは、あるトランザクションがデータを何度も読み込む場合、他のトランザクションがデータを挿入すると、読み取りタイミングによって結果が異なる。
Transaction Control
Oracle の SQL 文 COMMIT は、現在のトランザクションをコミットして、その変更を永続的なものにする。
COMMIT [ WORK ] [ COMMENT comment ]
[ WRITE [ WAIT | NOWAIT ] [ IMMEDIATE | BATCH ] ]
SQL> COMMIT WRITE WAIT;
SQL> COMMIT WRITE NOWAIT;
SQL> COMMIT WRITE IMMEDIATE;
SQL> COMMIT WRITE BATCH;
MySQL の SQL 文 COMMIT は、現在のトランザクションをコミットして、その変更を永続的なものにする。
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
PostgreSQL の SQL 文 COMMIT は、現在のトランザクションをコミットする。
COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
SQL Server の SQL 文 COMMIT は、正常終了した暗黙的または明示的なトランザクションの終点をマークする。
COMMIT [ { TRAN | TRANSACTION }
[ transaction_name | @tran_name_variable ] ]
[ WITH ( DELAYED_DURABILITY = { OFF | ON } ) ]
[ ; ]