如何在谷歌应用引擎中请求超时时处理写入事务

时间:2011-10-20 09:47:19

标签: google-app-engine

我是谷歌应用引擎的新手。我从昨天开始阅读app引擎。在请求超时期间,我对写入事务有疑问。

假设我正在创建10,000个对象并尝试通过单个事务进行保存(假设DatastoreService类似于Hibernate事务),就像这样

    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);
    }

假设在保存1000个对象后,请求超时将删除1000个对象?

我已经在app引擎上运行了这段代码,在将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那个

  

数据存储区可以在单个事务中执行多个操作。根据定义,除非事务中的每个操作都成功,否则事务不会成功。如果任何操作失败,则会自动回滚事务。这对于分布式Web应用程序尤其有用,其中多个用户可能同时访问或操作相同的数据。

任何人都可以帮我理解这一点。

提前谢谢大家。

2 个答案:

答案 0 :(得分:1)

GAE交易仅适用于实体组(具有相同root / parent的元素)。第二 - 它使用乐观锁定,这意味着当其他胎面在当前之前进行了更改时,交易失败。

这不是传统的交易。如果代码失败,您的对象将不会被删除

请阅读http://code.google.com/intl/en/appengine/docs/java/datastore/overview.html#Transactions_and_Entity_Groups

答案 1 :(得分:0)

我现在明白了如何处理写入数据存储区。使用此代码,我能够回滚在请求超时时保存的对象。首先,我尝试了这个代码,没有Thread.sleep(int)和i&lt; 10000。请求失败,当我转到我的数据存储区查看器时,我看不到任何新记录。然后我使用了Thread.sleep(int)和i&lt; 4并发送了一个请求。这次我可以在我的数据存储区查看器中看到记录。

我现在对交易和数据存储区有所了解。谢谢@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());
        }
    }
}