Spring 我们能用AOP简化编程事务管理吗?

Spring 我们能用AOP简化编程事务管理吗?,spring,spring-transactions,Spring,Spring Transactions,我想根据一些输入条件设置transactionManager,因此我从声明式事务管理转向了编程式事务管理 差不多 public User saveUser(NewUser newUser){ return transactionTemplate.execute(new TransactionCallback() { // the code in this method executes in a transactional context

我想根据一些输入条件设置transactionManager,因此我从声明式事务管理转向了编程式事务管理

差不多

public User saveUser(NewUser newUser){

     return transactionTemplate.execute(new TransactionCallback() {
              // the code in this method executes in a transactional context
              public Object doInTransaction(TransactionStatus status) {
                  try {
                        User savedObj = someService.saveUser(newUser);
        return savedObj ;
                } catch (DataManagerAPIException e) {
                    throw new RuntimeException(e);
                }
              }
            });
 }
一切正常,但将每个服务调用(我们的事务边界位于GWT客户机服务级别。类似于UI-->客户机服务-->服务-->Dao)与事务回调包装在一起会使代码比@Transactional更混乱。有没有更简单的方法?也许是基于AOP的方法

我尝试了以下方法

//Wrap every Client service method with a transaction.

@Around("execution(* com.myProject.server.service.*.*(..))")
public void transactionManagerProviderResult(final ProceedingJoinPoint pjp) {

    transactionTemplate.execute(new TransactionCallback() {

        @Override
        public Object doInTransaction(TransactionStatus status) {
            try {
                            Object result = pjp.proceed();
            return result ;
            } catch (Throwable e) {
                e.printStackTrace();
                return null;
            }
        }
    });
}

代码在事务上下文中运行良好,“result”包含正确的值(新保存的用户),但saveUser方法(GWT窗口小部件层)的调用方始终获取空对象。这不是GWT的问题,因为我也尝试独立于GWT。在“结果”之前,一切似乎都很好。在此之后,对象丢失。问题的可能原因和解决方案是什么?

调用方得到一个空对象,因为您没有从方法返回任何内容:

public Object transactionManagerProviderResult(final ProceedingJoinPoint pjp) {
    return transactionTemplate.execute(new TransactionCallback() {
        // ...

不太清楚为什么您需要自己执行此操作,而不是让
@Transactional
Spring支持为您执行此操作。

调用方获得空对象,因为您不从方法返回任何内容:

public Object transactionManagerProviderResult(final ProceedingJoinPoint pjp) {
    return transactionTemplate.execute(new TransactionCallback() {
        // ...

现在还不太清楚为什么您需要自己做这件事,而不是让
@Transactional
Spring支持为您做这件事。

+1 for
@Transactional
;它极大地简化了所有这些东西。(此外,即使你不想这样做——在有些情况下,其他选项更好——通过注释附加事务仍然是一种很好的方法,因为它很容易正确实现。)@JB Nizet——我完全同意你的看法。我这样做的原因是因为我需要切换事务管理器,如中所示。有没有更简单的方法可以做到这一点?没有经过测试,但是您是否尝试过定义一个FactoryBean,它根据某个ThreadLocal变量提供“英语”或“拉丁语”事务管理器,并使用这个FactoryBean作为您的主事务管理器?@JB Nizet-感谢您回答我最初的问题,即为什么我的代码不起作用。我真正需要的是一个AbstractRoutingDataSource。谢谢你的帮助。
@Transactional
+1;它极大地简化了所有这些东西。(此外,即使你不想这样做——在有些情况下,其他选项更好——通过注释附加事务仍然是一种很好的方法,因为它很容易正确实现。)@JB Nizet——我完全同意你的看法。我这样做的原因是因为我需要切换事务管理器,如中所示。有没有更简单的方法可以做到这一点?没有经过测试,但是您是否尝试过定义一个FactoryBean,它根据某个ThreadLocal变量提供“英语”或“拉丁语”事务管理器,并使用这个FactoryBean作为您的主事务管理器?@JB Nizet-感谢您回答我最初的问题,即为什么我的代码不起作用。我真正需要的是一个AbstractRoutingDataSource。谢谢你的帮助。