@OE_uia STM is a failure, since removed from Akka.
— Jamie Allen (@jamie_allen) September 28, 2014
9/28のAkka Meetupで、AkkaでTransaction処理する話題が出たときに、こんなことをつぶやいたら、Effective Akka著者の@jamie_allenさんに「それはもうオワコンだよ」と教えていただいた(確かに調べてみると、Akka 2.3でdeprecated)ので記事化してみる。
Akka Transactorsとは
Akka Transactors 公式ドキュメントより抜粋,翻訳。
Generally, the STM is not needed very often when working with Akka. Some use-cases (that we can think of) are:
- When you really need composable message flows across many actors updating their internal local state but need them to do that atomically in one big transaction. Might not be often but when you do need this then you are screwed without it.
- When you want to share a datastructure across actors.
一般的に、Akkaを使用しているときにSTMは殆どの場合必要ないけれども、(我々の考えている)ユースケースが幾つかある:
- 多数のアクター間の内部のローカルな状態を一つの大きなトランザクション内でアトミックに変更する為に合成可能なメッセージフローが必要なとき。こういうケースは余り頻繁にはないが、必要になったときTransactorsがないととても困るはずだ。
- データ構造をアクター間で共有したいとき
「Transactorsが無いととても困るはずだ」と書いておきながら、なんで削除されたのか気になったので聞いてみた。
Akka Transactorsが削除された理由
- Jamieさん曰く、非決定点?(some indeterminate point)においてSTMはライブロックに陥る可能性があるから。(STMのライブロックについてはこのあたりを参照。)
- Akka Teamの@patriknwさん曰く、Akka TransactorsはScalableでもDistributableでもないから。
- 上記二つは一応分けたけど、これはクラスター環境だとSTMがライブロックに陥りやすいので、ScalabilityやDistributabilityを損なう、ということな気がする(が間違っていたら教えてください)。
Akka Transactorsの代替手段
- 複数のActorの内部のローカルな状態をatomicに変更したいときは、short-lived actor(短命のアクター)を実装してその中でトランザクションを書く。
- トランザクションの書き方は、そのshort-lived actorのfailure内にロールバック処理を自前で実装するのが、JamieさんがEffective Akka内でもお勧めしている方法。
- でもshort-lived actor内のlocalな環境に限定すればSTMも使えるはず…なのだけど、そのことを聞いたら“No, no STM at all”と強く否定された。localな環境ならSTMはオーバースペックで、ロールバック処理さえあれば十分というだけのことかしら。
最後に
Effective AkkaのCameo Patternという項で、short-lived actorで複数のActorのをコーディネートする例が書かれているのでご参考までに(でもコーディネートするところだけで、トランザクションに相当するコードはない)。