1

Java Google App Engine 1.6.4.1 API に対していくつかのコードを書きました。コードをコンパイルするには、ConcurrentModificationException などの多くの例外を処理する必要がありました。1.6.5 にアップグレードしたところ、ほとんどの例外ハンドラーを削除するだけで、コードは正常にコンパイルされます。何が起こっている?

更新: いくつかのクラスの例外がスローされなくなりました。これはさまざまな例外のさまざまな理由で発生した可能性があるため、スローされなくなった例外を次に示します。

  • IllegalArgumentException

  • IllegalStateException

  • DatastoreFailureException

  • ConcurrentModificationException

GAE で IllegalArgumentException が発生した例を次に示します。Google App Engine - "java.lang.IllegalArgumentException: datastore transaction or write too big." これはもう発生しませんか?

Transaction Interface のドキュメントには、commit() を実行すると、最後の 3 つのいずれかを取得できると記載されています: https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/トランザクション#commit()

スロー:

java.lang.IllegalStateException - トランザクションがすでにコミットまたはロールバックされているか、(非同期呼び出しによって) コミットまたはロールバックが進行中の場合、またはコミットまたはロールバックの試行が既に失敗した場合。このメソッドが呼び出されたときに未処理の非同期データストア呼び出しがある場合、このメソッドは処理を進める前にそれらの呼び出しの完了をブロックします。

DatastoreFailureException - データストア エラーが発生した場合。

java.util.ConcurrentModificationException - 他のトランザクションが同じエンティティ グループを同時に変更した場合。

それでも、コードをコンパイルするためにそれらを処理する必要はなくなりました。これは奇妙に思えます。

4

2 に答える 2

2

<threadsafe>true</threadsafe>Google App Engine の最新リリースでは、appengine-web.xml でプロパティを設定する必要がありました。このリリースより前は、これは必要ありませんでした。

ConcurrentModificationExceptions は、アプリケーション内のオブジェクトの 1 つのインスタンスが複数のスレッドによって同時に変更されている場合に発生します。もちろん、これは一貫性のないデータと結果をもたらす可能性があり、一部のクラスは、不正なデータを返したり、データベースに一貫性のない変更を加えたりする代わりに、この例外をスローします。

threadsafe プロパティを true に設定すると、同時要求が有効になります。

同時リクエストの使用

デフォルトでは、App Engine は特定のウェブ サーバーにリクエストをシリアルに送信します。次の要素を appengine-web.xml に追加することで、複数のリクエストを並行して送信するように App Engine を構成できます。

<threadsafe>true</threadsafe>

1.6.5 より前では、threadsafe ディレクティブはオプションで、1.4.3 で導入されました。

Java applications can enable concurrent request support by setting <threadsafe>
to True in their appengine-web.xml. This flag indicates that request handlers
for your app are thread safe and multiple request handlers may safely run
at the same time in the same memory space for your application.

これは現在必須ですが、ConcurrentModificationExceptions が突然消えた正確な理由を説明するすぐに利用できる情報はないようです。1.4.3 リリース ノートで提案されているように、スレッド セーフにするためにコードを変更していない場合は、スレッド セーフの問題がまだ存在する可能性が高くなります。

1.4.3 リリースの詳細については、ブログ投稿Announce App Engine 1.4.3 Releaseを参照してください。

同時リクエスト: これまで、Java アプリケーションは追加のインスタンスを開始して、より高いトラフィック レベルに合わせて動的にスケールアップすることに依存していました。同時リクエストのサポートにより、各アプリケーション インスタンスは複数のユーザー リクエストを同時に処理できます。まず、アプリケーションのコードがスレッドセーフであることを確認してから、フラグを appengine-web.xml に追加して同時リクエストを有効にします。

報告した例外がなくなった場合でも、コードにスレッド セーフの問題が残っている可能性があります。インスタンスの数を増やしたか、ConcurrentModificationExceptions を軽減するためにアプリケーションで何か他のことを行ったために、これらが表示されない可能性があります。

1.6.5 がリリースされてから 1 か月も経っていないことを考えると、コードから例外ハンドラーを削除するのは非常にためらいます。結局のところ、彼らの仕事は発生した問題を検出して処理することであり、それらを削除すると、削除する前にあったかもしれない適切な劣化が失われます。

さらに、例外などの何かが存在しないことは、将来の未知の時点で何かが再び出現しないという証拠にはなりません。

ConcurrentModificationExceptionの javadoc から:

この例外は、そのような変更が許可されていない場合に、オブジェクトの同時変更を検出したメソッドによってスローされる場合があります。

たとえば、あるスレッドが Collection を変更しているときに、別のスレッドが Collection を反復処理することは一般的に許可されていません。一般に、反復の結果は、これらの状況では未定義です。一部の Iterator 実装 (JRE によって提供されるすべてのコレクション実装の実装を含む) は、この動作が検出された場合に、この例外をスローすることを選択する場合があります。これを行う反復子は、将来の不確定な時点で恣意的で非決定論的な動作を危険にさらすのではなく、迅速かつ明確に失敗するため、フェイルファスト反復子として知られています。

于 2012-05-19T03:18:15.010 に答える
0

Java Google App Engine 1.6.4.1 API に対していくつかのコードを書きました。コードをコンパイルするには、ConcurrentModificationException などの多くの例外を処理する必要がありました。

ここで奇妙なことがあります: ConcurrentModificationException と、あなたがリストしたその他の例外は、RuntimeException のサブクラスです。Java コンパイラーを満たすためにそれらをキャッチする必要はありません。

于 2012-05-24T16:54:55.893 に答える