0

我有一个 Spring + Hibernate + MySQL web 应用程序,它现在只是一个 hello-world-test-area。

我的一个服务类实现了这个方法:

public List<Offerta> tutte() {
        List<Offerta> tutte = null;
        TransactionStatus status = txm.getTransaction( new DefaultTransactionDefinition() );
        try {
            tutte = dao.getAll(Offerta.class);
            txm.commit(status);
        } catch (Exception e) {
            e.printStackTrace();
            txm.rollback(status);
        }
        return tutte;
    }

'txm' 是注入的 PlatformTransactionManager。

我现在想要的是避免在我的所有服务方法中重复“包装”事务代码!

我想要这样的东西:

someHelperTransactionClass.doThisInTransaction(new TransactionAction() {
  List l = dao.queryForSomething();
});

但这是一个内部类:我如何从中传入和传出数据?我的意思是,我怎样才能从那个 TransactionAction 中得到结果“l”列表?您可以通过多种方式回答这种特定情况,但我需要的是通用 TransactionAction 或不同的解决方案,让我编写实际的数据库代码,而不必每次都编写相同的无聊代码。

请不要回答“为什么不使用@Transactional 注释或AOP tx:advice 配置?” 因为我不能!为什么?我在 Google AppEngine 上,而那些很酷的人并不那么酷:对 javax.naming 包的禁用访问,以及声明性事务的那些很好的方式触及它。:-\

4

1 回答 1

1

您可以使用 Proxy 对象来模仿基本的 AOP 机制。如http://www.devx.com/Java/Article/21463/1954

这是一个模拟。但我真的怀疑它在 Spring 或 GAE 上的表现是否良好。请注意,您需要使用代理接口。

interface Dao {
    List<Foo> getAllFoo();
}

public class MyDao implements Dao {

    public MyDao() {
    }

    public List<Foo> getAllFoo() {
        //.. get list of foo from database. No need to use transactions
    }

    public static void main(String[] args) {
        Dao dao = new MyDao();
        InvocationHandler handler = new TransactionProxyHandler(dao);
        Dao proxy = (Dao) Proxy.newProxyInstance(MyDao.class.getClassLoader(), MyDao.class.getInterfaces(), handler);
        List<Foo> all = proxy.getAllFoo();
    }
}


class TransactionProxyHandler implements InvocationHandler {

    protected Object delegate;
    PlatformTransactionManager txm = new PlatformTransactionManager();

    public TransactionProxyHandler(Object delegate) {
        this.delegate = delegate;
    }

    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        TransactionStatus status = txm.getTransaction();
        Object res = null;
        try {
            res = method.invoke(delegate, args);
            txm.commit(status);
        } catch (Exception e) {
            e.printStackTrace();
            txm.rollback(status);
        }
        return res;
    }
}
于 2012-04-10T08:14:39.947 回答