1

appstatsを使用してこれを複数回確認しました。以下のコードがトランザクションにラップされていない場合、JDOは240のコストで2つのデータストア読み取りと1つの書き込み(3 RPC)を実行します。初回だけでなく、毎回同じレコードにアクセスしている場合でも、キャッシュからプルしています。ただし、上記のようにコードをトランザクションでラップすると、コードは4つのRPC(トランザクションの開始、get、put、commit)を作成します。これらのうち、Getのみがデータストアの読み取りとして請求されるため、全体のコストは70になります。

キャッシュからプルしている場合、なぜ読み取りに対してのみ請求するのでしょうか。読み取りではなく、書き込みに対して請求するように思われます。App Engineは、非トランザクションキャッシュ読み取りに対して、データストア読み取りと同じ金額を請求する可能性がありますか?なぜ?

これはコードWITHトランザクションです:

PersistenceManager pm = PMF.getManager();
Transaction tx = pm.currentTransaction();
String responsetext = "";
try {
  tx.begin();
  Key userkey = obtainUserKeyFromCookie();
  User u = pm.getObjectById(User.class, userkey);
  Key mapkey = obtainMapKeyFromQueryString();
  // this is NOT a java.util.Map, just FYI
  Map currentmap = pm.getObjectById(Map.class, mapkey);
  Text mapData = currentmap.getMapData(); // mapData is JSON stored in the entity
  Text newMapData = parseModifyAndReturn(mapData); // transform the map
  currentmap.setMapData(newMapData); // mutate the Map object
  tx.commit();
  responsetext = "OK";
} catch (JDOCanRetryException jdoe) {
  // log jdoe
  responsetext = "RETRY";
} catch (Exception e) {
  // log e
  responsetext = "ERROR";
} finally {
  if (tx.isActive()) {
    tx.rollback();
  }
  pm.close();
}
resp.getWriter().println(responsetext);

これは、トランザクションのないコードです。

PersistenceManager pm = PMF.getManager();
String responsetext = "";
try {
  Key userkey = obtainUserKeyFromCookie();
  User u = pm.getObjectById(User.class, userkey);
  Key mapkey = obtainMapKeyFromQueryString();
  // this is NOT a java.util.Map, just FYI
  Map currentmap = pm.getObjectById(Map.class, mapkey);
  Text mapData = currentmap.getMapData(); // mapData is JSON stored in the entity
  Text newMapData = parseModifyAndReturn(mapData); // transform the map
  currentmap.setMapData(newMapData); // mutate the Map object
  responsetext = "OK";
} catch (Exception e) {
  // log e
  responsetext = "ERROR";
} finally {
  pm.close();
}
resp.getWriter().println(responsetext);
4

1 に答える 1

2

トランザクションを使用すると、PersistenceManagerそのコードの処理全体でキャッシュが有効であることを知ることができます。トランザクションがなければ、キャッシュの内容を DB テーブルに対して検証する必要があります。チェックするたびに、そのためにトランザクションを作成する必要があります。これは DB インターフェース自体の機能であり、トランザクションに含まれていないアクション (いくつかの DB 固有の例外を除く) には、トランザクションが自動的に追加されます。

あなたの場合、処理中にデータベースの一貫したビューが必要なため、とにかくトランザクションが必要です。これがないと、mapData作業中に別の操作によって が変更される可能性があり、それらの変更は黙って失われます。それは悪いことです。(まあ、おそらく。) トランザクションは治療法です。

(トランザクション ラッピングを管理するために AOP を使用することも検討する必要があります。これは、トランザクション管理コードをすべて自分で毎回記述するよりもはるかに簡単です。OTOH、物事が正しくなるまで展開に多くの複雑さが追加される可能性があるため、私は理解できませんでした)このアドバイスに従って…)

于 2012-12-03T15:17:43.347 に答える