文章目录

  • 一、Spring中的template
  • 1.1 作用
  • 1.2 所需的依赖
  • 二、spring中的事务
  • 2.1 概述
  • 2.2 spring中的事务级别
  • 2.3 事务的传播行为
  • 2.4 超时时间
  • 2.5 是否是只读事务
  • 2.6 事务状态
  • 三、spring中事务测试
  • 3.1 spring中基于xml的声明式事务的配置
  • 3.2 spring中基于注解的声明式事务的配置步骤
  • 3.3 纯注解的事务配置
  • 3.4 编程式事务
  • 四、事务测试
  • 4.1 事务
  • 4.2 传播行为
  • 4.4.1 required
  • 4.4.2 required_new
  • 4.4.3 never
  • 4.4.4 NOT_SUPPORTED
  • 4.4.5 Propagation.NESTED
  • 4.4.6 Propagation.SUPPORTS


一、Spring中的template

1.1 作用

操作数据库的,实现对数据库的增删改查

1.2 所需的依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>2.2.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.18</version>
        </dependency>

二、spring中的事务

2.1 概述

spring事务是基于aop的,它可以使用编程的方式实现,也可以使用事务的方式实现。

TransactionDefinition类中包含了对事务的一些定义

2.2 spring中的事务级别

  • 作用是规定事务提交并发访问时的处理态度
int ISOLATION_DEFAULT = -1;
 可以读取未提交的数据
 int ISOLATION_READ_UNCOMMITTED = 1;
 只能读取已经提交的数据,解决脏读问题
 int ISOLATION_READ_COMMITTED = 2;
 是否读取其他事务提交修改后的数据,解决不可重复读问题
 int ISOLATION_REPEATABLE_READ = 4;
 是否读取其他事务提交添加后的数据,解决幻读问题
 int ISOLATION_SERIALIZABLE = 8;

2.3 事务的传播行为

int PROPAGATION_REQUIRED = 0;
 如果当前没有事务则新建一个事务,如果有事务,则加入事务。(默认选这个)
 int PROPAGATION_SUPPORTS = 1;
 支持当前事务,如果没有事务,则以非事务方式进行
 int PROPAGATION_MANDATORY = 2;
 使用当前事务,如果没有事务,则抛出异常
 int PROPAGATION_REQUIRES_NEW = 3;
 新建事务
 int PROPAGATION_NOT_SUPPORTED = 4;
 以非事务方式进行
 int PROPAGATION_NEVER = 5;
 以非事务方式进行,如果当前存在事务,则把当前事务挂起
 int PROPAGATION_NESTED = 6;
 当前有事务,则嵌套运行,无事务,按照PROPAGATION_REQUIRED方式进行

2.4 超时时间

  • 默认没有超时限制
int TIMEOUT_DEFAULT = -1;

2.5 是否是只读事务

  • 默认是false,建议查询时设置为只读
default boolean isReadOnly() {
        return false;
    }

2.6 事务状态

描述了事务在某个时间点上的状态信息

boolean isNewTransaction();
   //是否为新事务 
    void setRollbackOnly();
    //设置回滚点
    boolean isRollbackOnly();
   //是否回滚
    boolean isCompleted();
    //是否完成
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {
    boolean hasSavepoint();
    //是否有回滚点
    void flush();
    //刷新事务
}

三、spring中事务测试

3.1 spring中基于xml的声明式事务的配置

  • 配置事务管理器
  • 配置事务的通知
  • 配置aop中的通用切入点表达式
  • 建立事务通知和切入点表达式的对应关系
  • 配置事务的属性
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        https://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 配置业务层-->
    <!-- 配置账户持久层-->
    <!-- 配置数据源-->
    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/student"></property>
        <property name="username" value="ybx"></property>
        <property name="password" value="111111"></property>
    </bean>
    <!-- 配置事务的管理器-->
    <!-- ref就是上面配置的datasource -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource"></property>
    </bean>
    <!-- 配置事务的通知-->
    <!-- transaction-manager 给事务通知提供一个事务管理器的应用
         id                  事务通知的唯一标识-->
    <tx:advice id="txAAA" transaction-manager="transactionManager">
        <!-- 配置事务的属性-->
        <!-- rollback-for    指定一个异常,当该异常产生时,事务回滚,产生其他异常,事务不回滚,没有默认值,表示任何异常都回滚
             propagation     事务的传播行为
             no-rollback-for 指定一个异常,当该异常发生时,事物不回滚,没有默认值,表示任何异常都回滚
             isolation       事务的隔离级别
             read-only       设置为只读-->

        <tx:attributes>
            <!-- name:对方法名称的匹配-->
            <tx:method name="*" propagation="REQUIRED" read-only="false"></tx:method>
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method>
        </tx:attributes>
    </tx:advice>
    <!-- 配置aop的通用切入点表达式-->
    <aop:config>
        <aop:pointcut id="aopPoint" expression="execution(public * com.example.demo.Service.stuService.*(..))"/>
        <!-- 建立切入点表达式和事务通知的对应关系-->
        <aop:advisor advice-ref="txAAA" pointcut-ref="aopPoint"></aop:advisor>
    </aop:config>

</beans>

简单的说就是配置事务在serveice中哪些方法应用

3.2 spring中基于注解的声明式事务的配置步骤

注意:只有部分配置,配置不全<?xml version="1.0" encoding="UTF-8"?>

<tx:annotation-driven transaction-manager=“transactionManager”

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        https://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 配置业务层-->
    <!-- 配置账户持久层-->
    <!-- 配置数据源-->
    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/student"></property>
        <property name="username" value="ybx"></property>
        <property name="password" value="111111"></property>
    </bean>
    <!-- spring中基于注解的声明式事务的配置步骤
         1. 配置事务管理器
         2.开启spring对注解事务的支持
         3.在需要事务支持的地方使用@Transactional注解
         -->
    <!-- 配置事务的管理器-->
    <!-- ref就是上面配置的datasource -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource"></property>
    </bean>
    <!-- 开启spring对注解事务的支持-->
   <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>

3.3 纯注解的事务配置

  • 需要的配置类
@Configuration
@ComponentScan(basePackages = "com.example.demo")
@EnableTransactionManagement
public class txConfig {
    @Bean(value = "datasource")
    public DataSource getInstance1(){
        DriverManagerDataSource mysqlDataSource = new DriverManagerDataSource();
        mysqlDataSource.setUrl("jdbc:mysql://localhost:3306/student");
        mysqlDataSource.setPassword("510363");
        mysqlDataSource.setUsername("ybx");
        mysqlDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        System.out.println(mysqlDataSource.getUrl() + " " + mysqlDataSource.getUsername());
        return mysqlDataSource;
    }
    @Bean
    public PlatformTransactionManager getInstance(DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }
}

3.4 编程式事务

手动的将事务的内容编程到我们的代码中,比较麻烦。

四、事务测试

4.1 事务

4.2 传播行为

4.4.1 required

  • 没有事务,则新建事务执行,有则使用的事务。
  • 子出现异常,就算父捕获也会整体回滚

4.4.2 required_new

  • 无论外面是否有事务,都会创建新事务执行,每个事务都会单独执行,互不干扰。
  • 里外都是required_new,则哪里发生异常,后面的事务就不会再执行。

4.4.3 never

  • 以非事务进行,存在事务则抛出异常

4.4.4 NOT_SUPPORTED

  • 外层的传播行为是require
  • 嵌套方法B的传播行为NOT_SUPPORTED,为有事务则挂起事务,以非事务进行,存在异常,异常前的代码可以执行,异常后的代码不能执行,外层的事务遇到异常会回滚

4.4.5 Propagation.NESTED

  • 存在事务则新建事务嵌套运行,不存在事务则和required_new一致。
  • 存在事务,子发生异常,父如果捕捉子的异常,则子回滚,父不会回滚。父正常提交。

4.4.6 Propagation.SUPPORTS

  • 存在事务则加入事务,没有事务则以非事务进行。