TRANSACTION について
TRANSACTION はデータベースの排他制御を学ぶ上で大変重要な概念です。ここでは、本書で述べられている
SET TRANSACTION について、いくつか補足したいと思います。
SET TRANSACTION のオプションとして本書では
READ ONLY と READ WRITE を説明しています。本書では、話の流れ上、READ
ONLYを指定した場合、他のユーザーが変更できなくなると明記されていますが、これはかなり大胆な記述でして、実際は他のユーザーの変更が反映されなくなるという意味です。
言い換えると、READ ONLY を使って TRANSACTION
を開始した場合でも他のユーザーが別のセッションで現行ユーザーと同じ表を扱い、表の変更を行うことができます。
しかし、この変更は現行のユーザーには見えません。変更は、トランザクション終了後に反映することになります。
このように、1つのトランザクション中でデータが一意に保証されることを、一般にデータの一貫性が保たれるといいます。
なお、このような排他制御のレベルに関しては、各RDBMSによって仕様はさまざまです。一般に
Dirty read や Repeatable read のように呼ばれ、いくつかのレベルに分割されます。
ここでは、ORACLEを例に解説しています。
下記に READ ONLY および READ WEITE オプションを指定した例を記述しました。
(注)を参考にして頂けると、どのような違いがあるのかはっきりとわかると思います。
TEST 表
ID | LANG |
1 | JAPANESE |
この表に対して、User1, User2 以下のが以下の処理を行うとします。ここでは、User1 が SET TRANSACTION の READ WRITE オプションを使っています。
処理の流れ | User1の作業 | User1 から見た TEST表の内容 | User2 の作業 |
1 | SET TRANSACTION READ WRITE; | 1 JAPANESE | |
2 | UPDATE TEST SET LANG = 'ENGLISH' WHERE ID = 1; | ||
3 | SELECT * FROM TEST; | 1 JAPANESE | |
4 | COMMIT; | ||
5 | SELECT * FROM TEST; | 1 ENGLISH (注1) |
では、今度は User1 が SET TRANSACTION の READ
ONLY オプションを使った例です。
処理の流れ | User1の作業 | User1 から見た TEST表の内容 | User2 の作業 |
1 | SET TRANSACTION READ ONLY; | 1 JAPANESE | |
2 | UPDATE TEST SET LANG = 'ENGLISH' WHERE ID = 1; | ||
3 | SELECT * FROM TEST; | 1 JAPANESE | |
4 | COMMIT; | ||
5 | SELECT * FROM TEST; | 1 JAPANESE (注2) | |
6 | UPDATE TEST SET LANG = 'SPANISH' WHERE ID = 1 ; | (エラー) (注3) | |
7 | COMMIT; | ||
8 | SELECT * FROM TEST; | 1 ENGLISH (注4) |
(注1) User2 が変更を行い COMMIT が発行されたのでその時点で
User1 から見た場合も変更が反映されます。
(注2) User2 が変更を行い COMMIT が発行されましたが、READ
ONLY でトランザクションが開始されているため、変更が反映されません。
(注3) READ ONLY でトランザクションが開始されているため、表データの変更はできません。
(注4) 上のCOMMIT によってトランザクションが終了していますので、User2の変更が反映されています。