2011-10-20 10 views
1

私はGoogleのアプリエンジンのものに初心者です。私は昨日からアプリエンジンについて読んでいます。リクエストタイムアウト中にの書き込みトランザクションに関する疑問があります。Googleのアプリケーションエンジンで要求がタイムアウトしたときに書き込みトランザクションを処理する方法

私は万個のオブジェクトを作成し、単一のトランザクションによって救うためにそれをしようとしていたとしている1000個のオブジェクトを保存した後、その要求の時限とし、この

String greeting = "test"; 
    String guestBookName = "default"; 
    DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService(); 
    Key guestBookKey = KeyFactory.createKey("GuestBook", guestBookName); 
    for(int i=0;i<10000;i++) 
    { 
     Entity entity = new Entity("Greeting", guestBookKey); 
     entity.setProperty("date", new Date()); 
     entity.setProperty("greeting", greeting); 
     datastoreService.put(entity); 
    } 

のように(DatastoreServiceはHibernateのトランザクションのようなものであると仮定して) 1000個のオブジェクトが削除されますか?

私はアプリケーションエンジンでこのコードを実行しましたが、要求がタイムアウトしたデータストアに1164個のオブジェクトを保存しました。このエラーが発生しました

....Uncaught exception from servlet 
com.google.apphosting.api.DeadlineExceededException: This request (0000000000000000) 
started at 2011/10/20 07:18:36.726 UTC and was still executing at 2011/10/20 07:19:36.143 UTC..... 

オブジェクトはデータストアから削除されませんでした。私はhereを読みます。

データストアは、1回のトランザクションで複数の操作を実行できます。トランザクションのすべての操作が成功しない限り、トランザクションは正常に処理されません。いずれかの操作が失敗した場合、トランザクションは自動的にロールバックされます。これは、複数のユーザーが同時に同じデータにアクセスしたり操作したりする分散型Webアプリケーションに特に便利です。

誰もがこれについて明確に理解できるように助けてください。

ありがとうございます。

+0

私は私の質問に答えを見つけたと思う。私は次のことを行うことを考えています キャッチブロックを書きます。時間がなくなると、 "i"の値を記録し、 "i"をパラメータとして送信する同じリクエストにリダイレクトを再度送信します。 URLにパラメータが存在する場合、 "i"の値が取得され、残りのオブジェクトが保存されます。 アプローチは正しいですか? –

+0

より良い方法は、タスクキューでこれを行うことであり、ユーザーが直面する要求ではありません。また、すべてのエンティティを単一のエンティティグループに入れると、サポートできる更新レートに厳しい制限が課せられます。 –

+0

@NickJohnsonありがとうございます。私は詳細を得ることができる適切なリンクを私に送ってください。 –

答えて

1

GAEトランザクションはエンティティグループ(同じルート/親を持つ要素)に対してのみ動作します。もう1つはオプティミスティックロックを使用しています。これは、他のトレッドが現在よりも前に変更されたときにトランザクションが失敗することを意味します。

これは従来の取引ではありません。トランザクションコードが

私は今、データストアへの書き込みでの処理方法を理解http://code.google.com/intl/en/appengine/docs/java/datastore/overview.html#Transactions_and_Entity_Groups

+0

こんにちは、私はあなたの返信を理解できませんでした、あなたはそれを詳しく教えてください。ありがとう –

0

お読みください失敗した場合、あなたのオブジェクトが削除されません。このコードを使用すると、要求がタイムアウトした場合に保存されたオブジェクトをロールバックすることができました。最初にこのコードをThread.sleep(int)とi < 10000で試しました。リクエストが失敗し、Datastoreビューアに行ったときに新しいレコードが表示されませんでした。それから、私はでThread.sleep(int)を使い、リクエストを送りました。今回は、データストアビューアのレコードを見ることができました。

私はトランザクションとデータストアについて少し理解しました。ありがとう@splix

package guestbook; 

import java.io.IOException; 
import java.util.Date; 
import java.util.logging.Logger; 

import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import com.google.appengine.api.datastore.DatastoreService; 
import com.google.appengine.api.datastore.DatastoreServiceFactory; 
import com.google.appengine.api.datastore.Entity; 
import com.google.appengine.api.datastore.Key; 
import com.google.appengine.api.datastore.KeyFactory; 
import com.google.appengine.api.datastore.Transaction; 
import com.google.appengine.api.users.User; 
import com.google.appengine.api.users.UserService; 
import com.google.appengine.api.users.UserServiceFactory; 
import com.google.apphosting.api.DeadlineExceededException; 

@SuppressWarnings("serial") 
public class Test extends HttpServlet 
{ 
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException 
    { 
     Transaction transaction=null; 
     try 
     { 
      String greeting = "test"; 
      String guestBookName = "default"; 
      UserService userService = UserServiceFactory.getUserService(); 
      User user = userService.getCurrentUser(); 
      DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService(); 
      transaction = datastoreService.beginTransaction(); 
      Key guestBookKey = KeyFactory.createKey("GuestBook", guestBookName); 
      for(int i=0;i<4;i++) 
      { 
       Entity entity = new Entity("Greeting", guestBookKey); 
       entity.setProperty("user", user); 
       entity.setProperty("date", new Date()); 
       entity.setProperty("greeting", greeting+" "+i); 
       datastoreService.put(entity); 
       try { 
        Thread.sleep(1000*2); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
      transaction.commit(); 
     }catch(DeadlineExceededException e) 
     { 
      e.printStackTrace(); 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
     finally 
     { 
      Logger logger = Logger.getLogger(Test.class.getName()); 
      logger.info(""+transaction.isActive()); 
      if(transaction!=null) 
       if(transaction.isActive()) 
        transaction.rollback(); 
      logger.info(""+transaction.isActive()); 
     } 
    } 
} 
関連する問題