金曜日, 12月 11, 2009

【Google App Engine】 トランザクションのIsolation Levelについて


 ajn3のあおうささんのところで議論になったトランザクションのIsolation LevelがSERIALIZABLEであるという件。実はこれまでREAD COMMITEDじゃないかと思われていたふしがあった。ちょっとそれについて触れてみたい。
 そのように思い込まされた元凶がMaxさんの、 App Engine におけるトランザクション分離という記事。ここに、ははっきりと「Google App Engine データストアのトランザクション分離レベルは、Read Committed とほぼ同等です」とある。
 でもこれは、とりあえず、getTallPeople()がQueryだということで納得することにしよう。そもそもQueryはトランザクションに参加できないのでトランザクションの分離レベルの話をするには片手落ちである。Maxさんの記事は、分離レベルの話をしたいんじゃなくて、Datastore書き込みには2つのマイルストーンがあって、updatePerson()で実際にEntityやIndexを更新するタイミングによって見え方が異なるよという話がメインのような気がする。
 一方のajn3は、Low Level APIのGET/PUTの話。あるトランザクションのPUTがコミットされるタイミングと、同時に他のトランザクションでGETされるときのタイミングの話だった。GETとPUTのタイミングを考えると、SERIALIZABLE相当と考えるのが正しい。
 ちなみに、READ COMMITEDとSERIALIZABLEについては、以下の記事がわかりやすい。

トランザクションの隔離レベル

READ COMMITTEDに設定されている場合,トランザクションの実行中でも他のトランザクションによる更新処理や削除処理が行われれば,それらの処理が完了した時点から更新されたデータが参照されるようになる。一方,SERIALIZABLEに設定されている場合,トランザクションの実行中は他のトランザクションによるデータの更新処理や削除処理に関係なく,トランザクションが開始した時点のデータが参照される。つまり,SERIALIZABLEでは,他のトランザクションから完全に隔離された状態になる。


2 件のコメント:

  1. bufferings11/12/09 11:57

    英語版ドキュメントには
    Inside transactions: Serializable
    Outside transactions: Read Committed
    と書いてありますよー。

    http://code.google.com/intl/en/appengine/articles/transaction_isolation.html

    返信削除
  2. なんと。May 13, 2008 Revised May 2009となってますね。気がつきませんでした。早く日本語版も修正してほしいなあ・・・。

    返信削除