• @EnableTransactionManagement的使用


    Spring Boot 使用事务非常简单,首先使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactional 便可。

    关于事务管理器,不管是JPA还是JDBC等都实现自接口 PlatformTransactionManager 如果你添加的是 spring-boot-starter-jdbc 依赖,框架会默认注入 DataSourceTransactionManager 实例。如果你添加的是 spring-boot-starter-data-jpa 依赖,框架会默认注入 JpaTransactionManager 实例。

    你可以在启动类中添加如下方法,Debug测试,就能知道自动注入的是 PlatformTransactionManager 接口的哪个实现类。

    1. @EnableTransactionManagement // 启注解事务管理,等同于xml配置方式的 <tx:annotation-driven />
    2. @SpringBootApplication
    3. public class ProfiledemoApplication {
    4.  
    5. @Bean
    6. public Object testBean(PlatformTransactionManager platformTransactionManager){
    7. System.out.println(">>>>>>>>>>" + platformTransactionManager.getClass().getName());
    8. return new Object();
    9. }
    10.  
    11. public static void main(String[] args) {
    12. SpringApplication.run(ProfiledemoApplication.class, args);
    13. }
    14. }

    这些SpringBoot为我们自动做了,这些对我们并不透明,如果你项目做的比较大,添加的持久化依赖比较多,我们还是会选择人为的指定使用哪个事务管理器。 
    代码如下:

    1. @EnableTransactionManagement
    2. @SpringBootApplication
    3. public class ProfiledemoApplication {
    4.  
    5. // 其中 dataSource 框架会自动为我们注入
    6. @Bean
    7. public PlatformTransactionManager txManager(DataSource dataSource) {
    8. return new DataSourceTransactionManager(dataSource);
    9. }
    10.  
    11. @Bean
    12. public Object testBean(PlatformTransactionManager platformTransactionManager) {
    13. System.out.println(">>>>>>>>>>" + platformTransactionManager.getClass().getName());
    14. return new Object();
    15. }
    16.  
    17. public static void main(String[] args) {
    18. SpringApplication.run(ProfiledemoApplication.class, args);
    19. }
    20. }

    在Spring容器中,我们手工注解@Bean 将被优先加载,框架不会重新实例化其他的 PlatformTransactionManager 实现类。

    然后在Service中,被 @Transactional 注解的方法,将支持事务。如果注解在类上,则整个类的所有方法都默认支持事务。

    对于同一个工程中存在多个事务管理器要怎么处理,请看下面的实例,具体说明请看代码中的注释。

    1. @EnableTransactionManagement // 开启注解事务管理,等同于xml配置文件中的 <tx:annotation-driven />
    2. @SpringBootApplication
    3. public class ProfiledemoApplication implements TransactionManagementConfigurer {
    4.  
    5. @Resource(name="txManager2")
    6. private PlatformTransactionManager txManager2;
    7.  
    8. // 创建事务管理器1
    9. @Bean(name = "txManager1")
    10. public PlatformTransactionManager txManager(DataSource dataSource) {
    11. return new DataSourceTransactionManager(dataSource);
    12. }
    13.  
    14. // 创建事务管理器2
    15. @Bean(name = "txManager2")
    16. public PlatformTransactionManager txManager2(EntityManagerFactory factory) {
    17. return new JpaTransactionManager(factory);
    18. }
    19.  
    20. // 实现接口 TransactionManagementConfigurer 方法,其返回值代表在拥有多个事务管理器的情况下默认使用的事务管理器
    21. @Override
    22. public PlatformTransactionManager annotationDrivenTransactionManager() {
    23. return txManager2;
    24. }
    25.  
    26. public static void main(String[] args) {
    27. SpringApplication.run(ProfiledemoApplication.class, args);
    28. }
    29.  
    30. }
    1.  
    2. @Component
    3. public class DevSendMessage implements SendMessage {
    4.  
    5. // 使用value具体指定使用哪个事务管理器
    6. @Transactional(value="txManager1")
    7. @Override
    8. public void send() {
    9. System.out.println(">>>>>>>>Dev Send()<<<<<<<<");
    10. send2();
    11. }
    12.  
    13. // 在存在多个事务管理器的情况下,如果使用value具体指定
    14. // 则默认使用方法 annotationDrivenTransactionManager() 返回的事务管理器
    15. @Transactional
    16. public void send2() {
    17. System.out.println(">>>>>>>>Dev Send2()<<<<<<<<");
    18. }
    19.  
    20. }

    注: 
    如果Spring容器中存在多个 PlatformTransactionManager 实例,并且没有实现接口 TransactionManagementConfigurer 指定默认值,在我们在方法上使用注解 @Transactional 的时候,就必须要用value指定,如果不指定,则会抛出异常。

    对于系统需要提供默认事务管理的情况下,实现接口 TransactionManagementConfigurer 指定。

    对有的系统,为了避免不必要的问题,在业务中必须要明确指定 @Transactional 的 value 值的情况下。不建议实现接口 TransactionManagementConfigurer,这样控制台会明确抛出异常,开发人员就不会忘记主动指定。

  • 相关阅读:
    Rsync命令参数详解
    mysql 主从同步如何 把从数据的版本升级到指定的版本
    MySQL同步故障:" Slave_SQL_Running:No" 两种解决办法 (转)
    Linux VPS/服务器 网站及数据库自动本地备份并FTP上传备份脚本
    在kloxo中把不带www的域名做301到带www的域名
    mysql sorce 导入数据乱码问题解决
    linux后台运行和关闭SSH运行,查看后台任务
    centos下MySQL主从同步配置
    ecshop 无法上传产品图片 服务环境少了GD库
    EOJ2902 Contest
  • 原文地址:https://www.cnblogs.com/zhuyeshen/p/10907632.html
Copyright © 2020-2023  润新知