同一トランザクション内でエンキューできるタスクの上限

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)の上限は100件。
よって、同一トランザクション内でエンキューできるタスクは、5×100で500タスクということになる。