[バファリンズ]
半分はやさしくないものでできています
- 2010-12-28 bufferings
- 2010-12-28 soundTrick
- 2010-06-14 bufferings
- 2010-06-14 hiro_nemu
- 2010-05-10 bufferings
|
bufferings
[バファリンズ] 半分はやさしくないものでできています カテゴリー
カレンダー
最近のコメント
リンク
|
2010-06-09Slim3 Datastoreのputを読むSlim3 | | org.slim3.datastore.DatastoreputKey put(Entity entity) Key put(Object model) エンティティやモデルをデータストアに保存する。 Keyが返される。 List<Key> put(Iterable<?> models) List<Key> put(Object... models) batch put。複数のモデルやエンティティを一度の呼び出しで保存する。 一つずつputするよりもbatch putをする方が効率がいい。 このmodelsパラメータにはモデルとエンティティが混在していてもOK。 batch putで注意したいのは、Tx外で実行して書き込みエラーが発生したりタイムアウトになったりしても途中までのエンティティはデータストアに保存されているということ。 Key put(Transaction tx, Entity entity) Key put(Transaction tx, Object model) List<Key> put(Transaction tx, Iterable<?> models) List<Key> put(Transaction tx, Object... models) Tx指定を行うput。 Tx内では単一EG(エンティティグループ)のエンティティしか扱うことができないので、batch putを使用する場合には注意が必要。 このtxパラメータにnullを指定するとTx外で実行される。 put(Object model)のようにTx指定のないputを使用すると、カレントTxがあればそちらが使用されてしまうので、明示的にTxを示すためにもこちらのメソッドを使用した方がいいと思う。 また、Slim3には次のような便利メソッドも用意されている。 Key putWithoutTx(Entity entity) Key putWithoutTx(Object model) List<Key> putWithoutTx(Iterable<?> models) List<Key> putWithoutTx(Object... models) こちらはTx外で実行するメソッド。 中身は先程のputメソッドのtxパラメータにnullを指定して呼び出している。 コードの可読性のためにもTx外であればputWithoutTxを使用して、Txを使用する場合はput(tx,model)を使用すると良いだろう。 キーの自動生成put時にキーの自動生成をすることができるが、お勧めしない。 データストアへの書き込みは失敗する可能性がある。 putに失敗して例外が発生した場合でも、実際にはデータストアに書き込まれている場合があるのだ。 キーの自動生成をしていると再putでまたキーが自動生成されて同じエンティティ(モデル)が二つ登録されてしまう。 またTx外batch putの場合で、あるエンティティ(モデル)が書き込みに失敗した場合 そこまでのエンティティ(モデル)は既にデータストアに保存されている。 その場合キーの自動生成をしていると、既に保存されたデータは二重登録になってしまう。 ではどうするかというとallocateId(s)を使用して先にキーを生成しておく。 前もって生成しておいたキーを、エンティティ(モデル)に設定する。 そしてputするとキーは自動生成されず、再put時には上書きされるので二重登録されることはない。 ということなのだが。そこはSlim3。実はSlim3 Datastoreのput(Object model)を使用した場合は、putする前にallocateIdでキーを取得して設定してくれるのだ。 つまり、キーの自動生成はLow-level APIを直接使用している人は注意する必要があるが、Slim3を使用している人は気にしなくて良いてこと。 リトライSlim3が実装してくれている重要な機能にリトライ機能がある。 先程も言ったがGAEのデータストアはputに失敗する場合がある。 その際に発生する例外は2つある。一つはDatastoreTimeoutException。 データストアが忙しくて処理がタイムアウトしてしまった場合。タブレットの分割やマージの際に発生するようだ。 この場合は、すぐにリトライしても忙しいままだろうから少し待ってからリトライする。 それでも忙しければ、もうちょっと長く待ってからリトライする。というのをSlim3は10回リトライしてくれる。 それでもダメな場合に初めてSlim3はDatastoreTimeoutExceptionを投げる。 もう一つはConcurrentModificationException。こちらは同時更新時に発生。 普通はTxを使用している場合に発生するものだと思うのだが。Tx使用していなくても発生する場合があるらしい。 Txの更新競合が原因の場合はTxを再度始めないといけないのでリトライは開発者が行う必要があるが。 Txを使用していなくて発生した場合のことを考慮してリトライしてくれる。 これは待っても仕方がないのですぐにリトライする。 で、10回リトライしてダメだったらConcurrentModificationExceptionを投げる。 2010-06-11追記ココカラ txなしでConcurrentModificationExceptionって出るの? RT “@bufferings: 日記 #slim3 #appengine > Slim3 Datastoreのputを読む URL” Tx外のbatch putはEGごとにまとめられて内部的にはTxで実行されるので、CMEが発生します #appengine 2010-06-10 08:09:37 via web @higayasuo tx外のsingle putではCMEは発生しないのでしょうか? 2010-06-10 08:57:26 via twicca to @higayasuo @bufferings 自動的にRetryするので起きにくいはずですがある回数以上失敗すると起きるはず > tx外のsingle putではCMEは発生しないのでしょうか? #appengine 2010-06-10 09:59:51 via web to @bufferings ※補足:ここで言うリトライはSlim3のリトライのことではなく、失敗時にGAE側でリトライしてくれる機能のこと(v1.3.1で追加された)。 2010-06-11追記ココマデ 自動分割batch putには2つの制限がある。 だが。Slim3のbatch putには500個以上のエンティティを渡しても大丈夫だし。 合計1MBを超える数のエンティティを渡しても大丈夫。 なんとSlim3が計算して分割してくれるのだ。 素敵仕様。 Versionプロパティモデルのput時には@Attribute(version=true)のついたプロパティの値がインクリメントされる。 これは楽観的ロック用。 もうひとつputと名のつくメソッドがある。 boolean putUniqueValue(String uniqueIndexName, String value) これはuniqueIndexNameというKindでvalueというKeyNameのキーを持つエンティティをTx内でputすることで その一意性を保証するというメソッド。 勉強になったためになったね〜。ためになったよ〜。
トラックバック - http://d.hatena.ne.jp/bufferings/20100609/1276110414
リンク元
|