谷歌应用程序引擎数据存储上的嵌套事务3 [英] Nested transactions on google app engine datastore 3
问题描述
- 一旦在datastore.put(..)处的for循环中出现错误(假设i == 5 ),以前的放在同一行上的放置是否会回滚?
- 放置在saveRecord(..)中发生了什么?
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService()
Transaction txn = datastore.beginTransaction();
尝试{
for(int i = 0; 1 <10; i ++){
Key employeeKey = KeyFactory.createKey(Employee,Joe);
实体雇员= datastore.get(employeeKey);
employee.setProperty(vacationDays,10);
datastore.put(employee);
实体employeeRecord = createRecord(record,employeeKey);
saveRecord(employeeRecord);
}
txn.commit();
} finally {
if(txn.isActive()){
txn.rollback();
}
}
public void saveRecord(实体实体){
datastore.beginTransaction();
尝试{
//在这里做一些逻辑,删除活动并提交txn
datastore.put(entity);
} finally {
if(datastore.getCurrentTransaction()。isActive()){
datastore.getCurrentTransaction()。rollback();
解决方案好的,我假设您使用的是低级别数据存储区API。请注意,
getTransaction()
不存在。我假设你的意思是datastoreService.getCurrentTransaction()
。
$ bDatastoreService.beginTransaction() code>
将返回一个交易,即在您再次调用beginTransaction()
之前被视为同一线程上的当前交易。由于您在外部事务内的循环中调用beginTransaction()
,它会打破您的外部代码:循环完成后ds.getCurrentTransaction ()
不会返回相同的事务。此外,put()
隐式使用当前事务。因此,首先您必须修复外部代码以将事务保存为<示例中显示了一个href =https://developers.google.com/appengine/docs/java/datastore/transactions#Using_Transactions =nofollow>:
public void put(EventPlan eventPlan){
Transaction txn = ds.beginTransaction();
尝试{
for(final Activity activity:eventPlan.getActivities()){
save(activity,getPlanKey(eventPlan)); // PUT
//重要 - 也传递事务并使用它
//(我假设这是一些内部辅助方法)
ds.put(txn,activity,getSubPlanKey (eventPlan)); // subplan的父节点是eventPlan
}
txn.commit();
} finally {
if(txn.isActive())
txn.rollback();
现在回答问题:
是的,因为所有的投入现在都是同一个交易的一部分(修复代码之后),您可以调用
txn.rollback ()
就可以了。当然不是。他们是不同交易的一部分。
Question is: does ds.put(employee) happen in transaction? Or does the outer transaction get erased/overriden by the transaction in saveRecord(..)?
- Once error is thrown at line datastore.put(..) at some point in the for-loop (let's say i==5), will previous puts originating on the same line get rollbacked?
- What about puts happening in the saveRecord(..). I suppose those will not get rollbacked.
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService() Transaction txn = datastore.beginTransaction(); try { for (int i=0; 1<10; i++) { Key employeeKey = KeyFactory.createKey("Employee", "Joe"); Entity employee = datastore.get(employeeKey); employee.setProperty("vacationDays", 10); datastore.put(employee); Entity employeeRecord = createRecord("record", employeeKey); saveRecord(employeeRecord); } txn.commit(); } finally { if (txn.isActive()) { txn.rollback(); } } public void saveRecord(Entity entity) { datastore.beginTransaction(); try { // do some logic in here, delete activity and commit txn datastore.put(entity); } finally { if (datastore.getCurrentTransaction().isActive()) { datastore.getCurrentTransaction().rollback(); } } }
解决方案OK, I'll assume you are using low-level Datastore API. Note that
getTransaction()
does not exist. I'll assume you meantdatastoreService.getCurrentTransaction()
.
DatastoreService.beginTransaction()
will return a Transaction, that is considered a current transaction on the same thread until you callbeginTransaction()
again. Since you callbeginTransaction()
in a loop inside "outer" transaction, it breaks your "outer" code: after the loop is finishedds.getCurrentTransaction()
does not return the same transaction. Also,put()
implicitly uses current transaction.So first you must fix outer code to save transaction as shown in example:
public void put(EventPlan eventPlan) { Transaction txn = ds.beginTransaction(); try { for (final Activity activity : eventPlan.getActivities()) { save(activity, getPlanKey(eventPlan)); // PUT // IMPORTANT - also pass transaction and use it // (I assume this is some internal helper method) ds.put(txn, activity, getSubPlanKey(eventPlan)); //subplan's parent is eventPlan } txn.commit(); } finally { if (txn.isActive()) txn.rollback(); } }
Now on to questions:
Yes, because all puts are now part of the same transaction (after you fix the code) and you call
txn.rollback()
on it in case of errors.No, of course not. They are part of different transactions.
这篇关于谷歌应用程序引擎数据存储上的嵌套事务3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!