2013-05-10 74 views
0

在下面描述的情况中的JDO中,在methodB()被执行(已从methodA()中调用)之后,如果methodA()中发生异常,代码的回滚将发生在methodA()和methodB()或者methodA()中的方法B()提交已经发生。 注:PersistenceManager的是按需创建并存储在ThreadLocal的JDO本地事务管理

methodA(){ 


PersistenceManager mgr = getPersistenceManager(); 
    Transaction trans; 

    trans = mgr.currentTransaction(); 
    try { 
     trans.begin(); 
     methodB(); 

     //some delete/update code 
     // An exception occurs 

     trans.commit();   
    } 
    catch(Exception e) { 
     e.printStackTrace(); 
    } 
    finally { 
     if(trans.isActive()) { 
      trans.rollback(); 
     } 
     mgr.close(); 
    } 

}

的methodB(){

PersistenceManager mgr = getPersistenceManager(); 
    Transaction trans; 

    trans = mgr.currentTransaction(); 
    try { 
     trans.begin(); 
     //code 
     trans.commit();   
    } 
    catch(Exception e) { 
     e.printStackTrace(); 
    } 
    finally { 
     if(trans.isActive()) { 
      trans.rollback(); 
     } 
     mgr.close(); 
    } 

}

回答

0

事务不嵌套的,它们是独立的。 PMs不同,所以TXxns是不同的。一个失败,回滚,而且是无关的另一个

+0

明白了...这意味着如果我们用同样的PM那么这两个方法就会回滚。 – Jude 2013-05-12 05:38:10

+0

如果您使用过相同的PM,那么您只有一个事务(按照您通过阅读JDO规范所看到的内容),并且您在已经启动的事务上调用tx.begin()时会发生异常(所以你显然从来没有尝试过) – DataNucleus 2013-05-12 06:56:57

+0

我还没有尝试过,但是试图弄清楚如何构造代码,以便当从另一个事务方法调用事务方法B时,这两种方法都属于同一事务,并且当方法B即使这样,它仍然是事务性的。 – Jude 2013-05-12 11:23:31

0

了methodA和的methodB是两分部分不同的交易即非基本交易的理由: -

1>使用相同的PM实例两个不同的交易还没有按确保两个不同的事务总是使用相同的事务实例ID,因为不能保证要永久保持的嵌套方法B对象始终处于“持久清除”状态(保持对象处于脏状态的副作用),并且方法B事务没有像以前那样传播到方法A,而是在再次回到A之前得到提交。

2>交易不是上下文,因此交易将永远不会提交整个会话或方法序列。

3>如从spring模板引用的,对于一个特定的事务,一旦事务实例总是被检索并且整个事务完成,那么只有它被提交,([间接在jdo文档中间接提到: [1 ]:http://www.datanucleus.org/products/accessplatform_4_1/jdo/transactions.html#spring)。一种可能的方式是,方法A应该充当交易的主体或观察者,而方法B应该是订户,并且当所有订户都被通知针对特定交易时,则应该承诺交易。

欲了解更多请参考:Patterns for propagating changes to nested objects