前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作

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

作者头像
知了一笑
发布2019-07-19 15:00:13
5240
发布2019-07-19 15:00:13
举报
文章被收录于专栏:知了一笑知了一笑知了一笑

一、事务管理简介

1、基本概念

一组业务操作ABCD,要么全部成功,要么全部不成功。

2、特性:ACID

原子性:整体 一致性:完成 隔离性:并发 持久性:结果

3、隔离问题

脏读:一个事务读到另一个事务没有提交的数据 不可重复读:一个事务读到另一个事务已提交的数据(update) 虚读(幻读):一个事务读到另一个事务已提交的数据(insert)

4、隔离级别

read uncommitted:读未提交。 read committed:读已提交。解决脏读。 repeatable read:可重复读。解决:脏读、不可重复读。 serializable :串行化。都解决,单事务。

二、Spring管理事务

1、顶级接口

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

2、事务状态

3、事务定义

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
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 知了一笑 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、事务管理简介
    • 1、基本概念
      • 2、特性:ACID
        • 3、隔离问题
          • 4、隔离级别
          • 二、Spring管理事务
            • 1、顶级接口
              • 2、事务状态
                • 3、事务定义
                • 三、SpringBoot2.0管理事务
                  • 1、新建转账表
                    • 2、基于事务手动管理器
                      • 3、封装转账接口
                        • 4、封装三个测试接口
                          • 5、编写测试类
                          • 四、源代码地址
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档