2012-04-10 39 views
0

我有一個Spring + Hibernate + MySQL web應用程序,現在它只是一個hello-world-test-area。製作一個「TransactionAction」的內部類

我的一個服務類實現此方法:

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:建議配置?」因爲我不能! 爲什麼?我使用的是Google AppEngine,而那些酷玩家並不那麼酷:對javax.naming包的禁用訪問,以及那些用聲明式事務處理的好方法。 : - \

回答

1

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

這是一個模擬。但我真的懷疑它在Spring或GAE上表現不錯。請注意,您需要爲Proxies使用接口。

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; 
    } 
} 
+0

有趣但是....你能用一些僞代碼編輯你的答案嗎?只是爲了理解如何適用於我的情況。 – 2012-04-10 08:37:37

+0

請回答我! :) – 2012-04-10 10:06:01

相關問題