我有一个Spring + Hibernate + MySQL Web应用程序,现在只是一个hello-world-test-area。
我的一个Service类实现了这个方法:
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软件包的禁用访问,以及那些以声明式事务处理的好方式触及它。 : - \
答案 0 :(得分:1)
您可以使用代理对象模仿基本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;
}
}