[英]Google App Engine HR Datastore - Java - Delete Entities programatically
[英]Creating new Datastore entities with optimistic locking (Google App Engine Java / JPA)
我有一个JPA实体类User,用户名为@ID,没有父实体组。 我需要确保当两个并行事务尝试使用相同的用户名持久保存新用户时,只提交一个用户并回滚另一个用户。
例:
User bob = new User("bob");
EntityTransaction transaction = em.getTransaction();
try {
transaction.begin();
User u = em.find(User.class, bob.id());
if (u == null) {
em.persist(bob);
} else {
// identical user already existed before the transaction
throw new UserExistsException();
}
transaction.commit();
} catch (RollbackException e) {
// identical user was created during the transaction
throw new UserExistsException();
}
根据数据存储区文档,交易遵循乐观的锁定方法:
“当事务开始时,App Engine通过检查事务中使用的实体组的上次更新时间来使用乐观并发控制。在为实体组提交事务时,App Engine会再次检查上次使用的实体组的更新时间。如果它自我们的初始检查后发生了变化,App Engine会抛出异常。“ ( https://developers.google.com/appengine/docs/java/datastore/transactions )
在持久化事务之前不存在的新(根)实体时,这是否有效? 在我的情况下,App Engine会检查另一个事务是否同时持有具有相同ID的用户? 如果是这样,我是否需要一个明确的@Version字段用于此目的?
对此问题进行了一些长期的搁置:答案为“是”,上述代码应按预期工作。 简而言之,乐观并发控制机制将使用(根)实体的类型“用户”和给定标识符“bob”来比较两个事务中使用的(新)实体组。 数据存储区文档现在还明确地解决了创建案例:
当两个或多个事务尝试同时更改同一实体组时(更新现有实体或创建新实体),第一个提交事务将成功,所有其他事务将在提交时失败。
使用JPA,在这种情况下你会得到一个RollbackException。 低级API将引发ConcurrentModificationException。 如果您正在使用Objectify(我强烈建议),将自动重试失败的事务。 因此,您应该确保在事务中首先检查实体是否存在,除非您想在第二次尝试时覆盖它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.