【发布时间】:2013-02-09 01:39:32
【问题描述】:
我在我的项目中使用 Google Guice 和 jOOQ。目前我决定使用 Spring JDBC 引入事务处理。
所以我做了以下。
我在 Guice 模块中设置了数据源和事务管理器。
@Provides
@Singleton
DataSource provideDataSource(IExternalSettings settings) {
Jdbc3PoolingDataSource dataSource = new Jdbc3PoolingDataSource();
// configuring DataSource
return dataSource;
}
@Provides
@Singleton
DataSourceTransactionManager provideDataSourceTransactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(new TransactionAwareDataSourceProxy(dataSource));
}
然后我将我的事务管理器注入持久化外观
@Inject
public PersistenceFacade(final DataSourceTransactionManager transactionManager) {
this.dataSource = transactionManager.getDataSource();
this.transactionManager = transactionManager;
}
后来,我用这个数据源创建了jOOQ工厂:new Factory(dataSource, ...)。
最后我运行我的数据库访问代码:
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);
try {
// db code in transaction
transactionManager.commit(transaction);
return result;
} catch (Exception e) {
transactionManager.rollback(transaction);
throw e;
}
到目前为止,一切都很好。它按预期工作。
所以,我的下一步是使用 Guice AOP 引入 @Transactional 注释。我创建了一个拦截器
class TransactionalMethodInterceptor implements MethodInterceptor {
@Inject
private DataSourceTransactionManager transactionManager;
@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);
try {
Object result = invocation.proceed();
transactionManager.commit(transaction);
return result;
} catch (Exception e) {
transactionManager.rollback(transaction);
throw e;
}
}
}
并在Guice模块的configure()方法中配置:
TransactionalMethodInterceptor transactionalMethodInterceptor = new TransactionalMethodInterceptor();
requestInjection(transactionalMethodInterceptor);
bindInterceptor(Matchers.any(), Matchers.annotatedWith(Transactional.class), transactionalMethodInterceptor);
现在问题开始了。我可以看到,使用调试器,控制流到达拦截器。特别是,它达到了transactionManager.rollback(...) 调用。但事务实际上并未回滚。
我不知道是什么原因。有任何想法吗?我会很感激的。谢谢!
【问题讨论】:
-
调用invocation.proceed()的实例如何获取事务?
-
@AlenVrečko,Interceptor 注入了一个 transactionManager。它使用它来获得新的交易。不确定它是否能回答您的问题?
-
让我这么说吧,getConnection 在你的事务块中返回相同的连接吗?
-
我没有明确地打电话给
getConnection()。我将数据源传递给 jOOQ 的工厂并获得连接。然而,它在两种情况下都是一样的(即有和没有 AOP)。 -
导致控制流执行
rollback()的Exception e是什么?
标签: java transactions guice spring-jdbc jooq