对象化事务回滚没有发生
Objectify transaction rollback not happening
当我故意在 Objectify 事务中抛出异常时,我的事务没有被回滚。我做错了什么?
@Inject
Dao dao
...
public void testTransaction(){
dao.transact(new VoidWork() {
@Override
public void vrun() {
Key aclKey= dao.save().entity(acl).now(); //expecting this to be rolled back
//throw exception
if(true) throw new IllegalArgumentException();
//expecting rollback of acl save
}
});
}
我正在使用这样的设置:
@Singleton
public class DaoFactory extends ObjectifyFactory {
private Injector injector;
@Inject
public DaoFactory(Injector injector) {
this.injector = injector;
registerEntities();
}
private void registerEntities() {
}
@Override
public <T> T construct(Class<T> type) {
return injector.getInstance(type);
}
@Override
public Objectify begin() {
Dao dao = new Dao(this);
return dao;
}
}
其中:
public class Dao extends ObjectifyImpl<Dao> {
@Inject
public Dao(ObjectifyFactory fact) {
super(fact);
}
}
和
public class DaoService {
@Inject
public static void setObjectifyFactory(DaoFactory fact) {
ObjectifyService.setFactory(fact);
}
}
全部使用 Guice for DI 注入。
我单步执行了代码,objectify 确实在 TransactorNo.class
中调用了 txnOfy.getTransaction().rollback();
但是,当我检查应用程序引擎本地数据库时,我看到一个为 acl 创建的实体(有时需要几秒钟才能显示)
事务状态附加到特定的 ObjectifyImpl 实例。您正在开始一个事务(它通过静态 ofy()
方法使新的 ObjectifyImpl 可用),然后 重新使用 旧的非事务性 ObjectifyImpl 实例。
因此,即使您正在回滚事务,您的保存操作也会使用事务外部的非事务 Objectify impl。
这就是文档建议您永远不要在变量中保留 Objectify 实例的原因;始终使用静态 ofy()
方法。您可以制作自己的静态 ofy() (或其他)方法,而不是 returns 您的 Dao 类型。查看 http://www.motomapia.com/
的示例代码
因为事务和会话状态是线程本地问题,注入持久性上下文只是一个坏主意,即使在 JPA 下也是如此。
当我故意在 Objectify 事务中抛出异常时,我的事务没有被回滚。我做错了什么?
@Inject
Dao dao
...
public void testTransaction(){
dao.transact(new VoidWork() {
@Override
public void vrun() {
Key aclKey= dao.save().entity(acl).now(); //expecting this to be rolled back
//throw exception
if(true) throw new IllegalArgumentException();
//expecting rollback of acl save
}
});
}
我正在使用这样的设置:
@Singleton
public class DaoFactory extends ObjectifyFactory {
private Injector injector;
@Inject
public DaoFactory(Injector injector) {
this.injector = injector;
registerEntities();
}
private void registerEntities() {
}
@Override
public <T> T construct(Class<T> type) {
return injector.getInstance(type);
}
@Override
public Objectify begin() {
Dao dao = new Dao(this);
return dao;
}
}
其中:
public class Dao extends ObjectifyImpl<Dao> {
@Inject
public Dao(ObjectifyFactory fact) {
super(fact);
}
}
和
public class DaoService {
@Inject
public static void setObjectifyFactory(DaoFactory fact) {
ObjectifyService.setFactory(fact);
}
}
全部使用 Guice for DI 注入。
我单步执行了代码,objectify 确实在 TransactorNo.class
txnOfy.getTransaction().rollback();
但是,当我检查应用程序引擎本地数据库时,我看到一个为 acl 创建的实体(有时需要几秒钟才能显示)
事务状态附加到特定的 ObjectifyImpl 实例。您正在开始一个事务(它通过静态 ofy()
方法使新的 ObjectifyImpl 可用),然后 重新使用 旧的非事务性 ObjectifyImpl 实例。
因此,即使您正在回滚事务,您的保存操作也会使用事务外部的非事务 Objectify impl。
这就是文档建议您永远不要在变量中保留 Objectify 实例的原因;始终使用静态 ofy()
方法。您可以制作自己的静态 ofy() (或其他)方法,而不是 returns 您的 Dao 类型。查看 http://www.motomapia.com/
因为事务和会话状态是线程本地问题,注入持久性上下文只是一个坏主意,即使在 JPA 下也是如此。