同一トランザクション内でエンキューできるタスクの上限
App EngineのTask Queueにおいて、エンキューはトランザクション内でも行える。
Queue#add(Transaction, TaskOptions)を使う。
複数タスクの追加をtx内で試してみたところ、TransactionalTaskException(以下、TTE)が発生してエラーとなった。
Caused by:
com.google.appengine.api.labs.taskqueue.TransactionalTaskException
at com.google.appengine.api.labs.taskqueue.QueueApiHelper.translateError(QueueApiHelper.java:48)
at com.google.appengine.api.labs.taskqueue.QueueApiHelper.translateError(QueueApiHelper.java:111)
at com.google.appengine.api.labs.taskqueue.QueueApiHelper.makeSyncCall(QueueApiHelper.java:32)
at com.google.appengine.api.labs.taskqueue.QueueImpl.add(QueueImpl.java:310)
at com.google.appengine.api.labs.taskqueue.QueueImpl.add(QueueImpl.java:282)
at
(中略)
Caused by: java.lang.IllegalArgumentException: Too many messages, maximum allowed: 5
at com.google.appengine.api.datastore.DatastoreApiHelper.translateError(DatastoreApiHelper.java:34)
at com.google.appengine.api.labs.taskqueue.QueueApiHelper.translateError(QueueApiHelper.java:49)
... 40 more
javadocによると、Datastoreに例外が発生してキューの操作が失敗したときに発生するとのこと。
Queue operation failure caused by Datastore exception
TransactionalTaskException
スタックトレースによると今回のTTEはIllegalArgumentExceptionによって引き起こされている。
"Too many messages, maximum allowed: 5"とのことなので、下記のコードを試してみたところ、期待通りにTTE発生。addを5回以下にすると、TTEは発生しなかった。
public class EnqueueController extends Controller { @Override protected Navigation run() throws Exception { Transaction tx = Datastore.beginTransaction(); Queue queue = QueueFactory.getDefaultQueue(); queue.add(tx, TaskOptions.Builder.url("/hoge/count")); queue.add(tx, TaskOptions.Builder.url("/hoge/count")); queue.add(tx, TaskOptions.Builder.url("/hoge/count")); queue.add(tx, TaskOptions.Builder.url("/hoge/count")); queue.add(tx, TaskOptions.Builder.url("/hoge/count")); queue.add(tx, TaskOptions.Builder.url("/hoge/count")); tx.commit(); return null; } }
Queue#add(Iterable
よって、同一トランザクション内でエンキューできるタスクは、5×100で500タスクということになる。