在下面描述的情况下的JDO中,执行methodB()
之后(已经从methodA()
调用),如果在methodA()
中发生异常,则会在methodA()
和methodB()
或methodA()
中对代码进行回滚,因为在methodB()
中已经采取了地点。注意:PersistenceManager是按需创建的,并存储在ThreadLocal中
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( );
}
}
事务不是嵌套的,它们是独立的。 PM是不同的,因此txns是不同的。一个人没有回滚,与另一个无关
methodS和methodS是第二部分不同的事务i.n非原子事务的原因: -
1>对于两个不同的事务使用相同的PM实例也不能确保两个不同的事务使用相同的事务实例id总是因为不能保证嵌套的方法B对象被持久化处于'persistance-clean'状态总是(side)持久对象在脏状态下的影响)和方法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