zoukankan      html  css  js  c++  java
  • SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作

    本文源码:GitHub·点这里 || GitEE·点这里

    一、事务管理简介

    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
    GitEE·地址
    https://gitee.com/cicadasmile/spring-boot-base
    

  • 相关阅读:
    wordpress取文章时间
    一个链接引发的血案---------服务器 IO及网络流量暴涨解决历程
    wordpres 自定义comment样式
    HTML中head里的内容经浏览器解析后全到body里了
    mir9-lua——《热血沙城》45度ARPG手游-Lua移植版
    MoonWarriors-lua——《雷电战机》游戏-Lua移植版
    《QQ欢乐斗地主》山寨版
    最好的ie版本检测方式
    css 超出部分显示省略号
    分享一个jquery插件,弥补一下hover事件的小小不足
  • 原文地址:https://www.cnblogs.com/cicada-smile/p/11061439.html
Copyright © 2011-2022 走看看