一応動くのだが、たまに表示される結果にデータの変更内容が反映されていないことがある。
Google App Engine のデータストアの形式には以前は、「Master/Slave」形式と「High Replication」形式があったのだが、「Master/Slave」形式は廃止されて、現在はアプリケーションを作成する際には「High Replication」しか選択できないようになっている。
「High Replication」ではデータの取得が eventual である、すなわり取得したデータが最新ではない可能性があるとのこと。どうやらそのせいのようだ。
こんなコードで試してみた。
500件データを追加して直後に全件読み取りしてその件数を確認する。
または、全データを削除して直後に全件読み取りしてその件数を確認する。
... @SuppressWarnings("serial") public class EventualTestServlet extends HttpServlet { private static final int SIZE=500; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { PersistenceManager pm = PMF.get().getPersistenceManager(); try { execute(req); int count = countData(req); resp.setContentType("text/plain"); resp.getWriter().println("size=" + count); } finally { if ( pm !=null && ! pm.isClosed()) { pm.close(); }; } } private void execute(HttpServletRequest req) { PersistenceManager pm = PMF.get().getPersistenceManager(); try { String operation = req.getParameter("operation"); if ("add".equals(operation)) { for (int i=0; i<SIZE; i++) { MyData data = new MyData(); data.setName(req.getParameter("name")); pm.makePersistent(data); } } else if ("delete".equals(operation)) { Query query = pm.newQuery(MyData.class); @SuppressWarnings("unchecked") List<MyData> dataList = (List<MyData>)query.execute(); req.setAttribute("dataList", dataList); pm.deletePersistentAll(dataList); } } finally { pm.close(); } } public int countData(HttpServletRequest req) throws IOException { PersistenceManager pm = PMF.get().getPersistenceManager(); try { Query query = pm.newQuery(MyData.class); @SuppressWarnings("unchecked") List<MyData> dataList = (List<MyData>)query.execute(); pm.detachCopyAll(dataList); return dataList.size(); } finally { pm.close(); } } }
結果は 追加のほうは何回やっても500件カウントされている。一方削除のほうはたまに(10回に1回くらい)数件残ったりするようだ。もう一度(削除せずに)カウントだけし直すと0件になる。削除途中の結果が出てきているようだ。
ちなみに追加のほうは結構時間がかかるみたいで、500件でも30秒程度はかかっている。1000件だとタイムアウトしてしまった。
もう少しいろいろやってみようとしたのだが、
Uncaught exception from servlet com.google.apphosting.api.ApiProxy$OverQuotaException: The API call datastore_v3.Put() required more quota than is available.
とエラーになってしまった。「ただで使わせてあげてるのにやりすぎ」とのこと。
ごめんなさい。
0 件のコメント:
コメントを投稿