Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务

目录

一、事务的相关配置

1. 添加测试标签

2. 添加对应方法

3. 测试

二、事务的传播行为

三、事务的隔离级别

四、注解配置声明式事务

1. 注册事务注解驱动

2. 加上注解

3. 配置类代替xml文件中的注解事务支持

4. 测试

往期专栏&文章相关导读 

1. Maven系列专栏文章

2. Mybatis系列专栏文章

3. Spring系列专栏文章 


一、事务的相关配置

1. 添加测试标签

在 中可以进行事务的相关配置:

中的属性:

  1. name:指定配置的方法。 * 表示所有方法, find* 表示所有以find开头的方法。
  2. read-only:是否是只读事务,只读事务不存在数据的修改,数据库将会为只读事务提供一些
  3. 优化手段,会对性能有一定提升,建议在查询中开启只读事务。
  4. timeout:指定超时时间,在限定的时间内不能完成所有操作就会抛异常。默认永不超时
  5. rollback-for:指定某个异常事务回滚,其他异常不回滚。默认所有异常回滚。
  6. no-rollback-for:指定某个异常不回滚,其他异常回滚。默认所有异常回滚。
  7. propagation:事务的传播行为
  8. isolation:事务的隔离级别

添加 标签

    
    
        
            
            
        
    

2. 添加对应方法

        这里我们对查找用户id的时候进行用户修改,看看测试的时候是否报异常,因为上面我们已经设置了find方法开头为只读事务,不能对数据进行修改 

public Account findById(int id){
        Account account = accountDao.findById(1);
        account.setBalance(1000);
        accountDao.update(account);
        return accountDao.findById(id);
}

3. 测试

添加测试方法

    @Test
    public void testFindById(){
        Account account = accountService.findById(1);
        System.out.println(account);
    }

测试结果

Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务

OK,因此我们可以看到确实以find开头的方法确实是只能读取,不能修改。 

二、事务的传播行为

        事务传播行为是指多个含有事务的方法相互调用时,事务如何在这些方法间传播。

        如果在service层的方法中调用了其他的service方法,假设每次执行service方法都要开启事务,此时就无法保证外层方法和内层方法处于同一个事务当中。

例如:

// method1的所有方法在同一个事务中

public void method1(){

  // 此时会开启一个新事务,这就无法保证method1()

中所有的代码是在同一个事务中

  method2();

  System.out.println(“method1”);

}

public void method2(){

  System.out.println(“method2”);

}

        事务的传播特性就是解决这个问题的,Spring帮助我们将外层方法和内层方法放入同一事务中。

传播行为 介绍
REQUIRED 默认。支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
MANDATORY 支持当前事务,如果当前没有事务,就抛出异常。
REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED 必须在事务状态下执行,如果没有事务则新建事务,如果当前有事务则创建一个嵌套事务 

三、事务的隔离级别

        事务隔离级别反映事务提交并发访问时的处理态度,隔离级别越高,数据出问题的可能性越低,但效率也会越低。

隔离级别  脏读  不可重复读  幻读
READ_UNCOMMITED(读取未提交内容)  Yes  Yes  Yes 
READ_COMMITED(读取提交内容)  No Yes  Yes 
REPEATABLE_READ(重复读) No No Yes 
SERIALIZABLE(可串行化)  No No No

如果设置为DEFAULT会使用数据库的隔离级别。

  • SqlServer , Oracle默认的事务隔离级别是READ_COMMITED
  • Mysql的默认隔离级别是REPEATABLE_READ

四、注解配置声明式事务

Spring支持使用注解配置声明式事务。用法如下:

1. 注册事务注解驱动



2. 加上注解

在需要事务支持的方法或类上加@Transactional注解

package com.example.service;

import com.example.dao.AccountDao;
import com.example.pojo.Account;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
// 作用类上时,该类所有public方法将都具有该类型的事务属性
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
public class AccountService {
    @Autowired
    private AccountDao accountDao;


    /**
     *
     * @param id1 转出人id
     * @param id2 转入人id
     * @param price 金额
     */
    // 作用方法上时,该方法都将具有该类型事务的事务属性
    public void transfer(int id1,int id2, double price){

            // 转出人减少余额
            Account account1 = accountDao.findById(id1);
            account1.setBalance(account1.getBalance() - price);
            accountDao.update(account1);

            // 模拟程序出错
            int i = 1 / 0;

            // 转入人增加余额
            Account account2 = accountDao.findById(id2);
            account2.setBalance(account2.getBalance() + price);
            accountDao.update(account2);
       
    }
}

3. 配置类代替xml文件中的注解事务支持

配置类代替xml中的注解事务支持:需要在配置类上方写@EnableTranscationManagement

import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@Configuration
@ComponentScan("com.example")
@EnableTransactionManagement
public class SpringConfig {

    @Bean
    public DataSource getDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();

        druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        druidDataSource.setUrl("jdbc:mysql:///spring");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("666666");

        return druidDataSource;
    }

    @Bean
    public SqlSessionFactoryBean getSqlSession(DataSource dataSource){
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        sqlSessionFactoryBean.setDataSource(dataSource);

        return sqlSessionFactoryBean;
    }

    @Bean
    public MapperScannerConfigurer getMapperScanner(){
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();

        mapperScannerConfigurer.setBasePackage("com.example.dao");

        return mapperScannerConfigurer;
    }

    @Bean
    public DataSourceTransactionManager getTransactionManger(DataSource dataSource){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();

        dataSourceTransactionManager.setDataSource(dataSource);

        return dataSourceTransactionManager;
    }
}

4. 测试

添加测试方法

    // 测试注解配置类
    @Test
    public void testSpringConfig(){
        ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
        AccountService service = (AccountService) ac.getBean("accountService");
        accountService.transfer(1,2,500);
    }

测试结果

Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务

        OK,可以看到确实出现异常中断了,因此测试成功,Spring专栏也到此告一段落啦 ,接下来就开启了SpringMVC框架学习。希望大家可以持续关注啊!!!

往期专栏&文章相关导读 

     大家如果对于本期内容有什么不了解的话也可以去看看往期的内容,下面列出了博主往期精心制作的Maven,Mybatis等专栏系列文章,走过路过不要错过哎!如果对您有所帮助的话就点点赞,收藏一下啪。其中Spring专栏有些正在更,所以无法查看,但是当博主全部更完之后就可以看啦。

1. Maven系列专栏文章

Maven系列专栏 Maven工程开发
Maven聚合开发【实例详解—5555字】

2. Mybatis系列专栏文章

Mybatis系列专栏 MyBatis入门配置
Mybatis入门案例【超详细】
MyBatis配置文件 —— 相关标签详解
Mybatis模糊查询——三种定义参数方法和聚合查询、主键回填
Mybatis动态SQL查询 –(附实战案例–8888个字–88质量分)
Mybatis分页查询——四种传参方式
Mybatis一级缓存和二级缓存(带测试方法)
Mybatis分解式查询
Mybatis关联查询【附实战案例】
MyBatis注解开发—实现增删查改和动态SQL
MyBatis注解开发—实现自定义映射关系和关联查询

3. Spring系列专栏文章 

Spring系列专栏 Spring IOC 入门简介【自定义容器实例】
IOC使用Spring实现附实例详解
Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式
Spring DI简介及依赖注入方式和依赖注入类型
Spring IOC相关注解运用——上篇
Spring IOC相关注解运用——下篇
Spring AOP简介及相关案例
注解、原生Spring、SchemaBased三种方式实现AOP【附详细案例】
Spring事务简介及相关案例
Spring 事务管理方案和事务管理器及事务控制的API
Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/57b3f7e90a.html