Skip to content

Instantly share code, notes, and snippets.

@sinmetal
Created April 28, 2013 12:42
Show Gist options
  • Save sinmetal/5476777 to your computer and use it in GitHub Desktop.
Save sinmetal/5476777 to your computer and use it in GitHub Desktop.
package org.sinmetal.xgtx;
import java.io.IOException;
import java.util.ConcurrentModificationException;
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.EntityNotFoundException;
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.datastore.TransactionOptions;
@SuppressWarnings("serial")
public class XgtxServlet extends HttpServlet {
private final DatastoreService datastore = DatastoreServiceFactory
.getDatastoreService();
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
TransactionOptions options = TransactionOptions.Builder.withXG(true);
Transaction txn = datastore.beginTransaction(options);
get(txn, "A", "hoge", resp);
get(txn, "B", "fuga", resp);
get(txn, "C", "moga", resp);
Entity d = new Entity("D");
try {
datastore.put(txn, d);
} catch (Exception e) {
e.printStackTrace();
resp.getWriter().println("Kind(d) put. " + e.getMessage());
}
if (txn != null && txn.isActive()) {
try {
txn.commit();
} catch (Exception e) {
e.printStackTrace();
resp.getWriter().println("tx commit. " + e.getMessage());
}
} else {
resp.getWriter().println("transaction closed.");
}
resp.setContentType("text/plain");
resp.getWriter().println("Hello, XGTransaction");
}
private Entity get(Transaction txn, String kind, String key,
HttpServletResponse resp) throws IOException {
Key akey = KeyFactory.createKey(kind, key);
try {
return datastore.get(txn, akey);
} catch (EntityNotFoundException e) {
final String message = String.format(
"Kind(%s).Key(%s) entity NotFound.", kind, key);
resp.getWriter().println(message);
return null;
} catch (ConcurrentModificationException e) {
final String message = String
.format("Kind(%s).Key(%s) entity get ConcurrentModificationException.",
kind, key);
resp.getWriter().println(message);
return null;
}
}
}
@sinmetal
Copy link
Author

これを2回以上実行すると、以下の状態になる。

Kind(A).Key(hoge) entity NotFound.
Kind(B).Key(fuga) entity NotFound.
Kind(C).Key(moga) entity get ConcurrentModificationException.
Kind(d) put. transaction closed
tx commit. transaction closed
Hello, XGTransaction

Kind(C).Key(moga)がLockされたままになり、ConcurrentModificationExceptionが解消されない。
しかし、別のTxでKind(C).Key(moga)へアクセスすることはできる。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment