谷歌应用程序引擎数据存储上的嵌套事务3 [英] Nested transactions on google app engine datastore 3

查看:110
本文介绍了谷歌应用程序引擎数据存储上的嵌套事务3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题是:ds.put(员工)是否在交易中发生?或者外部事务是否被saveRecord(..)中的事务清除/重写?


  1. 一旦在datastore.put(..)处的for循环中出现错误(假设i == 5 ),以前的放在同一行上的放置是否会回滚?

  2. 放置在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()


$ b DatastoreService.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();


现在回答问题:


  1. 是的,因为所有的投入现在都是同一个交易的一部分(修复代码之后),您可以调用 txn.rollback ()就可以了。

  2. 当然不是。他们是不同交易的一部分。



Question is: does ds.put(employee) happen in transaction? Or does the outer transaction get erased/overriden by the transaction in saveRecord(..)?

  1. 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?
  2. 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 meant datastoreService.getCurrentTransaction().

DatastoreService.beginTransaction() will return a Transaction, that is considered a current transaction on the same thread until you call beginTransaction() again. Since you call beginTransaction() in a loop inside "outer" transaction, it breaks your "outer" code: after the loop is finished ds.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:

  1. 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.

  2. No, of course not. They are part of different transactions.

这篇关于谷歌应用程序引擎数据存储上的嵌套事务3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆