欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作

程序员文章站 2022-06-28 19:34:11
一、事务管理简介 1、事务基本概念 一组业务操作ABCD,要么全部成功,要么全部不成功。 2、特性:ACID 原子性:整体 一致性:完成 隔离性:并发 持久性:结果 3、隔离问题 脏读:一个事务读到另一个事务没有提交的数据 不可重复读:一个事务读到另一个事务已提交的数据(update) 虚读(幻读) ......
本文源码
github地址:知了一笑
https://github.com/cicadasmile/spring-boot-base

一、事务管理简介

1、事务基本概念
一组业务操作abcd,要么全部成功,要么全部不成功。
2、特性:acid
原子性:整体
一致性:完成
隔离性:并发
持久性:结果
3、隔离问题
脏读:一个事务读到另一个事务没有提交的数据
不可重复读:一个事务读到另一个事务已提交的数据(update)
虚读(幻读):一个事务读到另一个事务已提交的数据(insert)
4、隔离级别
read uncommitted:读未提交。
read committed:读已提交。解决脏读。
repeatable read:可重复读。解决:脏读、不可重复读。
serializable :串行化。都解决,单事务。

二、spring管理事务

1、*接口

SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作
1)platformtransactionmanager
平台事务管理器,spring要管理事务,必须使用事务管理器进行事务配置时,必须配置事务管理器。
2)transactiondefinition
事务详情(事务定义、事务属性),spring用于确定事务具体详情,
例如:隔离级别、是否只读、超时时间 等
进行事务配置时,必须配置详情。spring将配置项封装到该对象实例。
3)transactionstatus
事务状态,spring用于记录当前事务运行状态。例如:是否有保存点,事务是否完成。
spring底层根据状态进行相应操作。

2、事务状态

SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作

3、事务定义

SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作

propagation_required , required , 必须  【默认值】
    支持当前事务,a如果有事务,b将使用该事务。
    如果a没有事务,b将创建一个新的事务。
propagation_supports ,supports ,支持
    支持当前事务,a如果有事务,b将使用该事务。
    如果a没有事务,b将以非事务执行。
propagation_mandatory,mandatory ,强制
    支持当前事务,a如果有事务,b将使用该事务。
    如果a没有事务,b将抛异常。
propagation_requires_new , requires_new ,必须新的
    如果a有事务,将a的事务挂起,b创建一个新的事务
    如果a没有事务,b创建一个新的事务
propagation_not_supported ,not_supported ,不支持
    如果a有事务,将a的事务挂起,b将以非事务执行
    如果a没有事务,b将以非事务执行
propagation_never ,never,从不
    如果a有事务,b将抛异常
    如果a没有事务,b将以非事务执行
propagation_nested ,nested ,嵌套
    a和b底层采用保存点机制,形成嵌套事务。
掌握:propagation_required、propagation_requires_new、propagation_nested

三、springboot2.0管理事务

基于转账的案例演示,基于druid连接池配置。druid连接池在文章。

springboot2.0 基础案例(07):集成druid连接池,配置监控界面

1、新建转账表

create table account(
  id int primary key auto_increment,
  username varchar(50),
  money int
)engine=innodb default charset=utf8;
insert into account(username,money) values('jack','10000');
insert into account(username,money) values('rose','10000');
select * from account;

2、基于事务手动管理器

该配置用于测试事务的手动管理。

/**
 * 事物管理器
 */
@bean(name = "transactionmanager")
public platformtransactionmanager transactionmanager (druiddatasource datasource){
    logger.info("【transactionmanager 初始化...】");
    datasourcetransactionmanager transactionmanager = new datasourcetransactionmanager();
    transactionmanager.setdatasource(datasource);
    return transactionmanager;
}
/**
 * 创建事物手动管理模板
 */
@bean(name = "transactiontemplate")
public transactiontemplate transactiontemplate(platformtransactionmanager transactionmanager)
    logger.info("【transactiontemplate 初始化...】");
    transactiontemplate transactiontemplate = new transactiontemplate() ;
    transactiontemplate.settransactionmanager(transactionmanager);
    return transactiontemplate;
}

3、封装转账接口

接口方法

public interface accountservice {
    /**
     * 汇款
     */
    void out (string outer , integer money);
    /**
     * 收款
     */
    void in (string inner , integer money);
}

接口实现

@service
public class accountserviceimpl implements accountservice {
    @resource
    private jdbctemplate jdbctemplate ;
    public void out(string outer, integer money) {
        string sql = "update account set money = money - ? where username = ?";
        jdbctemplate.update(sql, money,outer);
    }
    public void in(string inner, integer money) {
        string sql = "update account set money = money + ? where username = ?";
        jdbctemplate.update(sql, money,inner);
    }
}

4、封装三个测试接口

测试接口

public interface tradeservice {
    /**
     * 转账交易:没有事务管理
     */
    void trade1(string outer ,string inner ,integer money);
    /**
     * 转账交易:手动管理事务
     */
    void trade2(string outer ,string inner ,integer money);
    /**
     * 转账交易:注解管理事务
     */
    void trade3(string outer ,string inner ,integer money);
}

接口实现

@service
public class tradeserviceimpl implements tradeservice {

    @resource
    private accountservice accountservice ;
    @resource
    private transactiontemplate transactiontemplate ;

    @override
    public void trade1(string outer, string inner, integer money) {
        accountservice.out(outer, money);
        // 抛出异常
        int i = 1/0;
        accountservice.in(inner, money);
    }

    @override
    public void trade2(string outer, string inner, integer money) {
        transactiontemplate.execute(new transactioncallbackwithoutresult() {
            public void dointransactionwithoutresult(transactionstatus arg0) {
                accountservice.out(outer, money);
                // 抛出异常
                int i = 1/0;
                accountservice.in(inner, money);
            }
        });
    }

    @transactional(value="transactionmanager",propagation= propagation.required)
    @override
    public void trade3(string outer, string inner, integer money) {
        accountservice.out(outer, money);
        // 抛出异常
        int i = 1/0;
        accountservice.in(inner, money);
    }
}

5、编写测试类

@runwith(springjunit4classrunner.class)
@springboottest(classes = transactionapplication.class)
public class tradetest {
    @resource
    private tradeservice tradeservice ;
    /**
     * 没有事务管理
     * jack 减少了1000块钱,但是rose得到1000块钱
     * 1    jack    9000
     * 2    rose    10000
     */
    @test
    public void testtrade1 (){
        tradeservice.trade1("jack", "rose", 1000);
    }
    /**
     * 手动管理事务
     * 1    jack    10000
     * 2    rose    10000
     */
    @test
    public void testtrade2 (){
        tradeservice.trade2("jack", "rose", 1000);
    }
    /**
     * 注解管理事务
     * 1    jack    10000
     * 2    rose    10000
     */
    @test
    public void testtrade3 (){
        tradeservice.trade3("jack", "rose", 1000);
    }
}

四、源代码地址

github地址:知了一笑
https://github.com/cicadasmile/spring-boot-base
码云地址:知了一笑
https://gitee.com/cicadasmile/spring-boot-base

SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作
SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作