我正在使用 gcloud-java-datastore API (v0.2.3) 来处理 Google Cloud Datastore。尝试使用事务来防止同时更新根实体,我似乎无法让事务按照我认为应该的方式工作。也许我的理解不正确,但绝对可以使用一些帮助。
下面是一个测试用例,其中两个线程在自己的事务中加载相同的实体,更新实体并提交。我希望一个线程的提交会成功,而另一个线程会失败。但是,每次,两个线程都通过覆盖第一个线程的更改而成功。这是预期的吗?根据https://cloud.google.com/datastore/docs/concepts/transactions上的官方文档,我解释说只有一笔交易会成功。
@Test
public void test2() {
Datastore datastore = DatastoreOptions.defaultInstance().service();
KeyFactory keyFactory = datastore.newKeyFactory();
com.google.cloud.datastore.Key key = keyFactory.kind("Account").newKey(5642398931615744L);
Runnable r = new Runnable() {
@Override
public void run() {
Transaction transaction = datastore.newTransaction();
try {
Entity entity = transaction.get(key);
System.out.println(entity);
Entity modifiedEntity = Entity.builder(entity).set("name", Thread.currentThread().getName())
.build();
transaction.put(modifiedEntity);
transaction.commit();
System.out.println(String.format("%1s: Commit successful", Thread.currentThread().getName()));
} catch (Exception exp) {
exp.printStackTrace();
} finally {
if (transaction.active()) {
transaction.rollback();
}
}
}
};
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException exp) {
exp.printStackTrace();
}
}
当我运行这个测试用例时,我在控制台上看到以下输出:
Thread-2: Commit successful
Thread-1: Commit successful
谢谢。