它是如何在这个Spring示例项目中声明事务管理器的?这个怎么运作?

时间:2014-12-28 11:26:45

标签: java spring spring-mvc transactions spring-transactions

我正在学习Spring Core认证,我发现一些与Spring处理事务有关的疑问。

所以我做了一个练习,我找到了类似的东西。

在名为 rewards.internal.RewardNetworkImpl 的班级中,我有这样的方法:

@Transactional
public RewardConfirmation rewardAccountFor(Dining dining) {
    Account account = accountRepository.findByCreditCard(dining.getCreditCardNumber());
    Restaurant restaurant = restaurantRepository.findByMerchantNumber(dining.getMerchantNumber());
    MonetaryAmount amount = restaurant.calculateBenefitFor(account, dining);
    AccountContribution contribution = account.makeContribution(amount);
    accountRepository.updateBeneficiaries(account);
    return rewardRepository.confirmReward(contribution, dining);
}

因此,此方法对某些服务类(基本上在数据库上执行某些查询)执行某些操作。我希望所有这些操作都执行到一个事务中(这保证了ACID属性)所以我使用 @Transactional 注释来注释这个方法。好的,我认为这对我来说非常清楚。

My Spring项目分为2个主文件夹(我认为是2个目录),包含相同的包)。这些文件夹分别命名为 src / test / java src / main / java 。第一个包含与 JUnit测试相关的类,第二个包含与实现应用程序的正确项目相关的类,这是如何组织我的项目的屏幕截图:

enter image description here

好的,现在在练习中它说我必须定义一个名为 transactionManager 的bean,它配置一个 DataSourceTransactionManager ,将此方法添加到名为的Spring配置类中rewards.SystemTestConfig 位于 src / test / java 文件夹中:

@Bean
public PlatformTransactionManager transactionManager() {
    return new DataSourceTransactionManager(dataSource());
}

因此,我很清楚这个方法配置了一个名为 transactionManager 的bean,该bean由 DataSourceTransactionManager 实现,使用 DataSource 对象。 / p>

我怀疑与此配置的位置有关。事实上,它被放在 src / test / java 文件夹中的 rewards.SystemTestConfig 内(包含 JUnit内容的文件夹

所以我的怀疑是:这种配置是仅与测试环境相关还是对我的整个项目来说是全局的? ( transactionManager 仅适用于测试环境,还是用于我的具体应用程序?)

我在 src / main / java 文件夹中有另一个配置类,这个:

package config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import rewards.RewardNetwork;
import rewards.internal.RewardNetworkImpl;
import rewards.internal.account.AccountRepository;
import rewards.internal.account.JdbcAccountRepository;
import rewards.internal.restaurant.JdbcRestaurantRepository;
import rewards.internal.restaurant.RestaurantRepository;
import rewards.internal.reward.JdbcRewardRepository;
import rewards.internal.reward.RewardRepository;


//  TODO-03: Add an annotation to instruct the container to look for the 
//  @Transactional annotation.  Save all work, run RewardNetworkTests.  It should pass.  

@Configuration
@EnableTransactionManagement
public class RewardsConfig {

    @Autowired
    DataSource dataSource;

    @Bean
    public RewardNetwork rewardNetwork(){
        return new RewardNetworkImpl(
            accountRepository(), 
            restaurantRepository(), 
            rewardRepository());
    }

    @Bean
    public AccountRepository accountRepository(){
        JdbcAccountRepository repository = new JdbcAccountRepository();
        repository.setDataSource(dataSource);
        return repository;
    }

    @Bean
    public RestaurantRepository restaurantRepository(){
        JdbcRestaurantRepository repository = new JdbcRestaurantRepository();
        repository.setDataSource(dataSource);
        return repository;
    }

    @Bean
    public RewardRepository rewardRepository(){
        JdbcRewardRepository repository = new JdbcRewardRepository();
        repository.setDataSource(dataSource);
        return repository;
    }

}

正如您所看到的,它不包含 transactionManager bean的显式配置,但它使用 @EnableTransactionManagement 注释进行了注释。我知道这个注释定义了一个代理@Transactional bean的Bean后处理器,因此发生了:

  • 包含在代理中的目标对象(使用环绕建议)

  • 代理实现以下行为:在输入方法之前启动事务并且在方法结束时提交并且如果方法抛出RuntimeException则回滚

但是我无法理解为什么在测试环境的 rewards.SystemTestConfig 配置类中,它显式地声明了 transactionManager bean并且在中RewardsConfig 类(配置正确应用程序的类)它没有被声明为 transactionManager (我认为这个bean绝对需要与事务一起运行)但是在它的位置有< strong> @EnableTransactionManagement 注释。

所以我怀疑是:

1)将 transactionManager bean声明为测试环境的 rewards.SystemTestConfig 配置类,它是全局的,它也适用于正确的应用程序文件夹(但我不是&# 39; t think)。

2)注意 @EnableTransactionManagement 注释 rewards.SystemTestConfig (配置正确的应用程序),它会自动创建一个事务管理器。但是什么样的?尤其是你怎么知道应该使用哪个数据源?

你能帮助我理解它是如何工作的吗?我错过了什么?

0 个答案:

没有答案