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

这篇具有很好参考价值的文章主要介绍了Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、事务的相关配置

1. 添加测试标签

2. 添加对应方法

3. 测试

二、事务的传播行为

三、事务的隔离级别

四、注解配置声明式事务

1. 注册事务注解驱动

2. 加上注解

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

4. 测试

往期专栏&文章相关导读 

1. Maven系列专栏文章

2. Mybatis系列专栏文章

3. Spring系列专栏文章 


一、事务的相关配置

1. 添加测试标签

在 <tx:advice> 中可以进行事务的相关配置:

<tx:method> 中的属性:

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

添加 <tx:advice>标签

    <!-- 进行事务相关配置 -->
    <tx:advice id = "txAdvice">
        <tx:attributes>
            <!-- 代表以find开头的方法 -->
            <tx:method name="find*" read-only="true"/>
        </tx:attributes>
    </tx:advice>

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. 注册事务注解驱动

<!-- 注册事务注解驱动 -->
<tx:annotation-driven transaction-manager="transactionManager">
</tx:annotation-driven>

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专栏有些正在更,所以无法查看,但是当博主全部更完之后就可以看啦。文章来源地址https://www.toymoban.com/news/detail-481739.html

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 事务的相关配置、传播行为、隔离级别及注解配置声明式事务

到了这里,关于Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring 事务(编程式事务、声明式事务@Transactional、事务隔离级别、事务传播机制)

    本篇重点总结: 在 Spring 项目中使用事务,有两种方式:编程式手动操作和声明式自动提交,声明式自动提交使用最多,只需要在方法上添加注解 @Transactional 设置事务的隔离级别 @Transactional(isolation = Isolation.SERIALIZABLE),Spring 中的事务隔离级别有5种 设置事务的传播机制 @Tra

    2024年02月03日
    浏览(42)
  • 【JavaEE】Spring事务-@Transactional参数介绍-事务的隔离级别以及传播机制

    【JavaEE】Spring 事务(2) 参数 作用 value 当配置了多个事务管理器时,可以使用该属性指定选择哪个事务管理器 transactionManager 当配置了多个事务管理器时,可以使用该属性指定选择哪个事务管理器 isolation 事务的隔离级别.默认值为solation.DEFAULT propagation 事务的传播机制,默认值

    2024年02月10日
    浏览(48)
  • Spring事务的四大特性+事务的传播机制+隔离机制

    原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 事务是一个原子操作, 由一系列动作组成。 组成一个事务的多个数据库操作是一个不可分割的原子单元 ,只有所有的操作执行成功,整个事务才提交。 事务中的任何一个数据库操作失败

    2024年01月20日
    浏览(38)
  • Spring的事务隔离级别

    Spring的事务隔离级别是用于控制事务并发访问数据库时的行为。Spring框架提供了五个事务隔离级别,分别是: 1. DEFAULT(默认):使用数据库默认的事务隔离级别。在大多数情况下,这等同于使用READ_COMMITTED级别。 2. READ_UNCOMMITTED(读取未提交数据):最低的隔离级别,允许一

    2024年02月09日
    浏览(41)
  • Spring事务隔离级别

    Spring事务隔离级别共有五种:DEFAULT、READ_UNCOMMITTED、READ_COMMITTED、REPEATBLE_READ、SERIALIZABLE。下面对这五个级别进行简单的介绍。 1 DEFAULT Spring中 默认 的事务隔离级别。以连接的数据库的事务隔离级别为准。 2 READ_UNCOMMITTED Spring事务 最弱 的隔离级别。一个事务可以读取到另一个

    2024年02月09日
    浏览(43)
  • Spring 事务的使用、隔离级别、@Transactional的使用

            Spring事务是Spring框架提供的一种机制,用于管理应用程序中的数据库事务。         事务是一组数据库操作的执行单元,要么全部成功提交,要么全部失败回滚,保证数据的一致性和完整性。 Spring事务提供了声明式事务和编程式事务两种方式: 编程式事务:

    2024年02月15日
    浏览(44)
  • 38、Spring事务的实现方式和原理以及隔离级别

    在使用Spring框架时,可以有两种使用事务的方式,一种是编程式的,一种是申明式的,@Transactional注解就是申明式的。 首先,事务这个概念是数据库层面的,Spring只是基于数据库中的事务进行了扩展,以及提供了一些能让程序员更加方便操作事务的方式。 比如我们可以通过在

    2024年02月16日
    浏览(42)
  • spring-transaction源码分析(1)概述和事务传播级别

    spring-tx包使用注解驱动和AOP通知将事务开启、提交/回滚、以及复杂的传播机制封装了起来,开发者不再需要编写事务管理的代码,而是可以只关注自己的业务逻辑。 本文将简单介绍spring-tx使用步骤以及七种事务传播级别。 后续文章会阅读源码,深入分析spring-tx aop通知、七种

    2024年02月03日
    浏览(42)
  • 【Spring/MySQL数据库系列】数据库事务的特点与隔离级别

    ⭐️ 前面的话 ⭐️ 本文已经收录到《Spring框架全家桶系列》专栏,本文将介绍有关数据库事务的特点以及隔离级别。 📒博客主页:未见花闻的博客主页 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 📌本文由 未见花闻 原创, CSDN 首发! 📆首发时间:🌴2023年5月20日🌴 ✉️坚

    2024年02月05日
    浏览(53)
  • Spring @Transactional注解事务传播机制propagation参数说明

    在SpringBoot项目中,我们通常使用 @Transactional 去进行事务控制,而 @Transactional 注解中,有个比较关键的属性就是 propagation 。在一个 多事务 的环境中,一个事务方法调用另一个事务方法时,就会涉及到事务的传播行为,该属性用来控制一段代码经过多个 @Transactional 注解生效(

    2024年02月11日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包