0

私は Spring + Hibernate + MySQL Web アプリケーションを持っていますが、これは今のところ単なる hello-world-test-area です。

私の Service クラスの 1 つは、このメソッドを実装しています。

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 に答える