我在我的项目中使用 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;
}
到现在为止还挺好。它按预期工作。
所以,我的下一步是@Transactional
使用 Guice AOP 引入注解。我创建了一个拦截器
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;
}
}
}
configure()
并在Guice 模块的方法中配置它:
TransactionalMethodInterceptor transactionalMethodInterceptor = new TransactionalMethodInterceptor();
requestInjection(transactionalMethodInterceptor);
bindInterceptor(Matchers.any(), Matchers.annotatedWith(Transactional.class), transactionalMethodInterceptor);
现在问题开始了。我可以看到,使用调试器,控制流到达拦截器。特别是,它到达transactionManager.rollback(...)
调用。但事务实际上并没有回滚。
我不知道是什么原因。有任何想法吗?我会很感激的。谢谢!