Spring Boot 指定事务管理器

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

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

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

打印项目事务管理器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@EnableTransactionManagement // 启注解事务管理,等同于xml配置方式的 <tx:annotation-driven />
@SpringBootApplication
public class TransactionDemoApplication {

@Bean
public Object testBean(PlatformTransactionManager platformTransactionManager){
System.out.println(">>>>>>>>>>" + platformTransactionManager.getClass().getName());
return new Object();
}

public static void main(String[] args) {
SpringApplication.run(TransactionDemoApplication.class, args);
}
}

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

指定事务管理器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@EnableTransactionManagement
@SpringBootApplication
public class TransactionDemoApplication {

// 其中 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(TransactionDemoApplication.class, args);
}
}

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

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

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

使用指定的事务管理器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@EnableTransactionManagement // 开启注解事务管理,等同于xml配置文件中的 <tx:annotation-driven />
@SpringBootApplication
public class TransactionDemoApplication 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(TransactionDemoApplication.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()<<<<<<<<");
}
}

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :