はじめに
GS2 におけるトランザクションとは、GS2-Showcase の商品購入APIの戻り値 や GS2-Exchange の交換実行API の戻り値です。
このような複数のマイクロサービスの値を書き換える動作は非同期処理で実行されます。
この処理単位を 「トランザクション」 と呼んでいます。
そして、8月には非同期処理の完了を待てるように SDK を拡張しました。
機能追加の背景
ガチャを例に説明します。ガチャは一般的に以下のプロセスで実行されます。
消費「GS2-Money から課金通貨を300減らす」
入手「GS2-Lottery でガチャを実行する」
そして、ガチャを実行すると新しいトランザクションが発行されます。
消費 なし
入手「ガチャで排出されたキャラクターを GS2-Inventory に格納する」
8月に追加した内容は、トランザクション内で新しいトランザクションが発生した時にその結果も待つかどうかのオプションがあります。
var transaction = await gs2.Showcase( "namespace" ).Me( gameSession ).Showcase( "showcase" ).DisplayItem( "displayItem" ).BuyAsync( 1 ); await transaction.WaitAsync();
このように記述すると
消費「GS2-Money から課金通貨を300減らす」 入手「GS2-Lottery でガチャを実行する」
の部分だけを待って、アイテムの入手処理は終わっていない状態で処理が返ります。
これによって、通信待ちの時間を最小にして抽選結果に応じた演出を開始し、抽選の演出している間にアイテムの付与が行えました。
var transaction = await gs2.Showcase( "namespace" ).Me( gameSession ).Showcase( "showcase" ).DisplayItem( "lottery1" ).BuyAsync( 1 ); await transaction.WaitAsync(true);
このように記述すると
消費「GS2-Money から課金通貨を300減らす」 入手「GS2-Lottery でガチャを実行する」 消費 なし 入手「ガチャで排出されたキャラクターを GS2-Inventory に格納する」
の全てを待つことができました。
しかし、これではトランザクションがもう少し複雑な構造を持っている場合に、完全に処理を待つことしかできませんでした。
追加された機能の詳細
WaitAsync の第一引数に何も指定しない場合に続きのトランザクションオブジェクトを返すようになりました。
この機能の実例として複雑なトランザクションを追いながら解説します。
10連ガチャで9個と1個で異なる GS2-Lottery の抽選ロジックを適用する場合を考えてみましょう。
最初のトランザクションは
消費「GS2-Money から課金通貨を3000減らす」 入手「GS2-Lottery で LotteryA を9回実行する」 入手「GS2-Lottery で LotteryB を1回実行する」
となりますが、このような入手処理が複数存在する場合は GS2 においてはジョブキューを経由するように変換されます。
つまり、以下のようになります。
消費「GS2-Money から課金通貨を3000減らす」 入手「GS2-JobQueue に《GS2-Lottery で LotteryA を9回実行する》と《GS2-Lottery で LotteryB を1回実行する》ジョブを登録」
JobQueue を実行し 《GS2-Lottery で LotteryA を9回実行する》と《GS2-Lottery で LotteryB を1回実行する》を実行し、最大10個のトランザクションを発行 (最大としているのは同一アイテムが排出された場合、トランザクション処理の最適化処理で数が減ることがあるため)
入手「ガチャで排出されたキャラクターを GS2-Inventory に格納する」× 最大10個
内部的には 最大11個のトランザクション、2個のジョブキューで構成されますが
SDK上は開発者がより直感的に扱えるように、上記の3段階のトランザクションステップで扱い、トランザクションステップ単位で処理を待つことができるようになりました。
つまり、改めてコードを示すと
var transaction = await gs2.Showcase( "namespace" ).Me( gameSession ).Showcase( "showcase" ).DisplayItem( "lottery10" ).BuyAsync( 1 ); var transaction2 = await transaction.WaitAsync(); await transaction2.WaitAsync();
と記述することで、2つ目のトランザクションステップまで実行を待つことができます。
つまり
消費「GS2-Money から課金通貨を3000減らす」 入手「GS2-JobQueue に《GS2-Lottery で LotteryA を9回実行する》と《GS2-Lottery で LotteryB を1回実行する》ジョブを登録」 JobQueue を実行し 《GS2-Lottery で LotteryA を9回実行する》と《GS2-Lottery で LotteryB を1回実行する》を実行し、最大10個のトランザクションを発行
までということになります。
これで、ガチャの抽選結果が確定しつつ、アイテムをインベントリに追加する前までトランザクション処理を待つことができるようになりました。