Spring Boot 使用事务很是简单,首先使用注解 @EnableTransactionManagement 开启事务支持后,而后在访问数据库的Service方法上添加注解 @Transactional 即可。java
关于事务管理器,无论是JPA仍是JDBC等都实现自接口 PlatformTransactionManager 若是你添加的是 spring-boot-starter-jdbc 依赖,框架会默认注入 DataSourceTransactionManager 实例。若是你添加的是 spring-boot-starter-data-jpa 依赖,框架会默认注入 JpaTransactionManager 实例。spring
你能够在启动类中添加以下方法,Debug测试,就能知道自动注入的是 PlatformTransactionManager 接口的哪一个实现类。数据库
@EnableTransactionManagement // 启注解事务管理,等同于xml配置方式的 <tx:annotation-driven /> public class TransactionConfig { @Bean public Object testBean(PlatformTransactionManager platformTransactionManager){ System.out.println(">>>>>>>>>>" + platformTransactionManager.getClass().getName()); return new Object(); } }
这些SpringBoot为咱们自动作了,这些对咱们并不透明,若是你项目作的比较大,添加的持久化依赖比较多,咱们仍是会选择人为的指定使用哪一个事务管理器。
代码以下:框架
@EnableTransactionManagement @SpringBootApplication public class ProfiledemoApplication { // 其中 dataSource 框架会自动为咱们注入 @Bean public PlatformTransactionManager txManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean public Object testBean(PlatformTransactionManager platformTransactionManager) { System.out.println(">>>>>>>>>>" + platformTransactionManager.getClass().getName()); return new Object(); } public static void main(String[] args) { SpringApplication.run(ProfiledemoApplication.class, args); } }
在Spring容器中,咱们手工注解@Bean 将被优先加载,框架不会从新实例化其余的 PlatformTransactionManager 实现类。ide
而后在Service中,被 @Transactional 注解的方法,将支持事务。若是注解在类上,则整个类的全部方法都默认支持事务。spring-boot
对于同一个工程中存在多个事务管理器要怎么处理,请看下面的实例,具体说明请看代码中的注释。测试
@EnableTransactionManagement // 开启注解事务管理,等同于xml配置文件中的 <tx:annotation-driven /> @SpringBootApplication public class ProfiledemoApplication implements TransactionManagementConfigurer { @Resource(name="txManager2") private PlatformTransactionManager txManager2; // 建立事务管理器1 @Bean(name = "txManager1") public PlatformTransactionManager txManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } // 建立事务管理器2 @Bean(name = "txManager2") public PlatformTransactionManager txManager2(EntityManagerFactory factory) { return new JpaTransactionManager(factory); } // 实现接口 TransactionManagementConfigurer 方法,其返回值表明在拥有多个事务管理器的状况下默认使用的事务管理器 @Override public PlatformTransactionManager annotationDrivenTransactionManager() { return txManager2; } public static void main(String[] args) { SpringApplication.run(ProfiledemoApplication.class, args); } }
@Component public class DevSendMessage implements SendMessage { // 使用value具体指定使用哪一个事务管理器 @Transactional(value="txManager1") @Override public void send() { System.out.println(">>>>>>>>Dev Send()<<<<<<<<"); send2(); } // 在存在多个事务管理器的状况下,若是使用value具体指定 // 则默认使用方法 annotationDrivenTransactionManager() 返回的事务管理器 @Transactional public void send2() { System.out.println(">>>>>>>>Dev Send2()<<<<<<<<"); } }
注:
若是Spring容器中存在多个 PlatformTransactionManager 实例,而且没有实现接口 TransactionManagementConfigurer 指定默认值,在咱们在方法上使用注解 @Transactional 的时候,就必需要用value指定,若是不指定,则会抛出异常。.net
对于系统须要提供默认事务管理的状况下,实现接口 TransactionManagementConfigurer 指定。code
对有的系统,为了不没必要要的问题,在业务中必需要明确指定 @Transactional 的 value 值的状况下。不建议实现接口 TransactionManagementConfigurer,这样控制台会明确抛出异常,开发人员就不会忘记主动指定。orm