Objectify事务回滚没有发生

时间:2015-03-02 06:29:41

标签: objectify google-cloud-datastore

当我故意在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注入DI。

我介绍了代码,客观化确实在txnOfy.getTransaction().rollback();

中调用了TransactorNo.class

但是,当我检查app-engine本地数据库时,我看到为acl创建了一个实体(有时需要几秒钟才能显示)

1 个答案:

答案 0 :(得分:4)

事务状态附加到特定的ObjectifyImpl实例。您正在启动一个事务(通过静态ofy()方法使新的ObjectifyImpl可用),然后重新使用旧的非事务性ObjectifyImpl实例。

因此,即使您正在回滚交易,您的保存操作也会利用交易外部的非事务性Objectify impl。

这就是为什么文档表明你永远不会在变量中持有Objectify实例的原因;始终使用静态ofy()方法。您可以创建自己的静态ofy()(或其他)方法来返回您的Dao类型。查看http://www.motomapia.com/

的示例代码

因为事务和会话状态是线程局部关注的问题,所以即使在JPA下,注入持久化上下文也是一个坏主意。