我是谷歌应用引擎的新手。我从昨天开始阅读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应用程序尤其有用,其中多个用户可能同时访问或操作相同的数据。
任何人都可以帮我理解这一点。
提前谢谢大家。
答案 0 :(得分:1)
GAE交易仅适用于实体组(具有相同root / parent的元素)。第二 - 它使用乐观锁定,这意味着当其他胎面在当前之前进行了更改时,交易失败。
这不是传统的交易。如果代码失败,您的对象将不会被删除
答案 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());
}
}
}