当前位置: 移动技术网 > IT编程>开发语言>Java > SpringBoot 源码解析 (八)----- Spring Boot 精髓:事务源码解析

SpringBoot 源码解析 (八)----- Spring Boot 精髓:事务源码解析

2019年11月25日  | 移动技术网IT编程  | 我要评论

今日逢君君不识,全能侍卫,niouniou

本篇来讲一下springboot是怎么自动开启事务的,我们先来回顾一下以前ssm中是如何使用事务的

ssm使用事务

导入jdbc依赖包

众所周知,凡是需要跟数据库打交道的,基本上都要添加jdbc的依赖,在spring项目中,加入的是spring-jdbc依赖:

<dependency>
    <groupid>org.springframework</groupid>
    <artifactid>spring-jdbc</artifactid>
</dependency>

配置版事务

在使用配置文件的方式中,通常会在spring的配置文件中配置事务管理器,并注入数据源:

<!-- 注册数据源 -->
<bean id="datasource" class="...">
    <property name="" value=""/>
</bean>

<!-- 注册事务管理器 -->
<bean id="txmanager" class="org.springframework.jdbc.datasource.datasourcetransactionmanager">
    <property name="datasource" ref="datasource" />
</bean>

<!-- 开启事务注解 -->
<tx:annotation-driven transaction-manager="txmanager" />

接下来可以直接在业务层service的方法上或者类上添加@transactional

注解版事务

首先需要注册两个bean,分别对应上面spring配置文件中的两个bean:

@enabletransactionmanagement//重要
@configuration
public class txconfig {

    @bean
    public datasource datasource() {
        combopooleddatasource datasource = new combopooleddatasource();
        datasource.setuser("...");
        datasource.setpassword("...");
        datasource.setdriverclass("...");
        datasource.setjdbcurl("...");
        return datasource;
    }
  
    //重要
    @bean
    public platformtransactionmanager platformtransactionmanager() {
        return new datasourcetransactionmanager(datasource());//放入数据源
    }
}

我们看到往spring容器中注入了datasource 和platformtransactionmanager 对象,并且通过@enabletransactionmanagement注解开启了事务,和上面的xml配置是一一对应的。platformtransactionmanager这个bean非常重要,要使用事务管理,就必须要在ioc容器中注册一个事务管理器。

public interface platformtransactionmanager {
    //获取一个transaction
    transactionstatus gettransaction(transactiondefinition var1) throws transactionexception;
    //提交事务
    void commit(transactionstatus var1) throws transactionexception;
    //回滚事务
    void rollback(transactionstatus var1) throws transactionexception;
}

我们看到事务管理器的作用就是获取事务,提交回滚事务。datasourcetransactionmanager是platformtransactionmanager的一个实现类,大家可以看看我以前的文章spring5 源码深度解析----- spring事务 是怎么通过aop实现的?(100%理解spring事务) 看一下spring的声明式事务的源码。下面我们来看看springboot是如何自动配置事务的

springboot自动配置事务

引入jdbc

众所周知,在springboot中凡是需要跟数据库打交道的,基本上都要显式或者隐式添加jdbc的依赖:

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-jdbc</artifactid>
</dependency>

也就是jdbc的场景启动器,我们点进去看看

其实也是引入了spring-jdbc的依赖,接下来我们要看两个重要的事务自动配置类

datasourcetransactionmanagerautoconfiguration

我们看到在spring.factories中配置了事务管理器自动配置类datasourcetransactionmanagerautoconfiguration,我们进去看看

 1 @configuration
 2 //在类路径下有这个类存在platformtransactionmanager时,这个配置类才会生效
 3 //而前面我们已经引入了spring-boot-starter-jdbc,那自然是存在了
 4 @conditionalonclass({ jdbctemplate.class, platformtransactionmanager.class })
 5 @autoconfigureorder(ordered.lowest_precedence)
 6 @enableconfigurationproperties(datasourceproperties.class)
 7 public class datasourcetransactionmanagerautoconfiguration {
 8 
 9     @configuration
10     @conditionalonsinglecandidate(datasource.class)
11     static class datasourcetransactionmanagerconfiguration {
12 
13         private final datasource datasource;
14 
15         private final transactionmanagercustomizers transactionmanagercustomizers;
16 
17         datasourcetransactionmanagerconfiguration(datasource datasource,
18                 objectprovider<transactionmanagercustomizers> transactionmanagercustomizers) {
19             this.datasource = datasource;
20             this.transactionmanagercustomizers = transactionmanagercustomizers
21                     .getifavailable();
22         }
23 
24         @bean
25         //没有当spring容器中不存在platformtransactionmanager这个对象时,创建datasourcetransactionmanager
26         //也就是如果我们自定义了datasourcetransactionmanager并注入spring容器,这里将不会执行
27         @conditionalonmissingbean(platformtransactionmanager.class)
28         public datasourcetransactionmanager transactionmanager(datasourceproperties properties) {
29             //创建datasourcetransactionmanager注入spring容器,并且把datasource传进去
30             datasourcetransactionmanager transactionmanager = new datasourcetransactionmanager(this.datasource);
31             if (this.transactionmanagercustomizers != null) {
32                 this.transactionmanagercustomizers.customize(transactionmanager);
33             }
34             return transactionmanager;
35         }
36 
37     }
38 
39 }

很明显只要我们导入了spring-boot-starter-jdbc场景启动器,并且我们没有自定义datasourcetransactionmanager,那么事务管理器自动配置类datasourcetransactionmanagerautoconfiguration会自动为我们创建datasourcetransactionmanager并注入spring容器中。但是这还不够,我们前面还是需要通过@enabletransactionmanagement开启事务呢,如果不开启事务,@transactional是不起任何作用的。下面我们就来看看是如何开启事务的

transactionautoconfiguration

我们看到在spring.factories中配置了事务自动开启配置类transactionautoconfiguration,我们进去看看

 1 @configuration
 2 //和datasourcetransactionmanagerautoconfiguration中是一样的
 3 //引入了spring-boot-starter-jdbc,那自然是存在了platformtransactionmanager
 4 @conditionalonclass({platformtransactionmanager.class})
 5 //这个自动配置类必须要在datasourcetransactionmanagerautoconfiguration这个自动配置类之后才能生效
 6 //也就是前面我们已经往spring容器中注入了datasourcetransactionmanager这个对象才执行这个配置类
 7 @autoconfigureafter({jtaautoconfiguration.class, hibernatejpaautoconfiguration.class, datasourcetransactionmanagerautoconfiguration.class, neo4jdataautoconfiguration.class})
 8 @enableconfigurationproperties({transactionproperties.class})
 9 public class transactionautoconfiguration {
10     public transactionautoconfiguration() {
11     }
12 
13     @configuration
14     @conditionalonbean({platformtransactionmanager.class})
15     @conditionalonmissingbean({abstracttransactionmanagementconfiguration.class})
16     public static class enabletransactionmanagementconfiguration {
17         public enabletransactionmanagementconfiguration() {
18         }
19 
20         @configuration
21         //重点:通过 @enabletransactionmanagement注解开启事务
22         //可以看到和我们自己使用@enabletransactionmanagement是一样的
23         @enabletransactionmanagement(
24             proxytargetclass = true
25         )
26         @conditionalonproperty(
27             prefix = "spring.aop",
28             name = {"proxy-target-class"},
29             havingvalue = "true",
30             matchifmissing = true
31         )
32         public static class cglibautoproxyconfiguration {
33             public cglibautoproxyconfiguration() {
34             }
35         }
36 
37         @configuration
38         @enabletransactionmanagement(
39             proxytargetclass = false
40         )
41         @conditionalonproperty(
42             prefix = "spring.aop",
43             name = {"proxy-target-class"},
44             havingvalue = "false",
45             matchifmissing = false
46         )
47         public static class jdkdynamicautoproxyconfiguration {
48             public jdkdynamicautoproxyconfiguration() {
49             }
50         }
51     }
52 
53     @configuration
54     @conditionalonsinglecandidate(platformtransactionmanager.class)
55     public static class transactiontemplateconfiguration {
56         private final platformtransactionmanager transactionmanager;
57 
58         public transactiontemplateconfiguration(platformtransactionmanager transactionmanager) {
59             this.transactionmanager = transactionmanager;
60         }
61 
62         @bean
63         @conditionalonmissingbean
64         public transactiontemplate transactiontemplate() {
65             return new transactiontemplate(this.transactionmanager);
66         }
67     }
68 }

我们看到transactionautoconfiguration这个自动配置类必须要在datasourcetransactionmanagerautoconfiguration这个配置类之后才能生效,也就是前面我们已经往spring容器中注入了datasourcetransactionmanager这个对象才执行这个配置类,然后通过

@enabletransactionmanagement这个注解开启事务,其实和我们自己使用@enabletransactionmanagement是一样的

因此,只要我们在springboot中引入了spring-boot-starter-jdbc这个场景启动器,就会帮我们自动开启事务了,我们只需要使用@transactional就可以了

mybatis-spring-boot-starter

大多数时候我们在springboot中会引入mybatis这个orm框架,mybaits的场景启动器如下

<dependency>
  <groupid>org.mybatis.spring.boot</groupid>
  <artifactid>mybatis-spring-boot-starter</artifactid>
  <version>1.3.0</version>
</dependency>

我们点进去看看

我们看到mybatis-spring-boot-starter这个场景启动器是引入了spring-boot-starter-jdbc这个场景启动器的,因此只要我们在springboot中使用mybaits,是自动帮我们开启了spring事务的

总结

springboot 开启事物很简单,只需要加一行注解@transactional就可以了,前提你用的是jdbctemplate, jpa, mybatis,这种常见的orm。

日常求赞

好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是人才。

如果这个文章写得还不错,觉得学到了一点东西的话 求点赞

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网