• SSM学习——Spring事务(9)


    感谢黑马!

    事务

    事务作用:在数据层保障一系列的数据库操作同成功同失败
    Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败

    其实简单来说就是,我一段insert命令要执行好几百个参数,然后运行到50个的时候,断电了,担心数据库只保存了我前面50个,相当于这是条没用的数据,然而,事务便帮我们纠正了:如果这一段没运行完就发生错误,那我就全部回滚,整个都先撤回了。

    其实,spring拓展了业务层的事务,其实是能保障我们同时的许许多多的数据层处于同一事务状态——因为一个业务层很可能调用了好多的数据层(是为了保障组合功能中事务生效的)

    spring提供了这个接口来保障的:
    在这里插入图片描述

    同时,spring提供了这个实现类
    在这里插入图片描述

    案例

    模拟银行账户间的转账业务
    需求微缩:A账户扣钱,B账户加钱
    同时保证:程序出现异常之后,整体业务必须失败

    在这里插入图片描述

    实现

    数据库

    我们先建好表

    use 20220806lige;
    
    drop table if exists tb_account;
    
    create table tb_account
    (
        id       int primary key auto_increment,
        username varchar(20),
        money    double
    );
    
    
    
    INSERT INTO tb_account
    VALUES (1, '张三', 1000);
    INSERT INTO tb_account
    VALUES (2, '李四', 1000);
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    配置基本环境

    jdbc.properties需要在数据库url参数后面添加:useSSL=false&useServerPrepStmts=true&useUnicode=true&characterEncoding=utf8

    整体使用spring整合mybatis+注解开发使用
    在这里插入图片描述

    Dao层接口

    @Update("update tb_account set money = money + #{money} where username = #{name}")
        void inMoney(@Param("name") String name, @Param("money") Double money);
    
        @Update("update tb_account set money = money - #{money} where username = #{name}")
        void outMoney(@Param("name") String name, @Param("money") Double money);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    业务层接口很简单:

    public interface AccountService {
        /**
         * 转账操作
         * @param out 传出方
         * @param in 转入方
         * @param money 金额
         */
        public void transfer(String out,String in ,Double money) ;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    实现类也很简单:

    @Service
    public class AccountServiceImpl implements AccountService {
    
        @Autowired
        private AccountDao accountDao;
    
        public void transfer(String out,String in ,Double money) {
            //A转出money
            accountDao.outMoney(out,money);
            //B转入money
            accountDao.inMoney(in,money);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    我们使用测试类执行

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = SpringConfig.class)
    public class AccountServiceTest {
    
        @Autowired
        private AccountService accountService;
    
        @Test
        public void testTransfer() throws IOException {
            accountService.transfer("Tom","Jerry",100D);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    事务同步方法

    1,在需要用到spring事务的接口处开启@Transactional
    在这里插入图片描述

    2,在JdbcConfig中配置事务管理器

    //配置事务管理器,mybatis使用的是jdbc事务
        @Bean
        public PlatformTransactionManager transactionManager(DataSource dataSource) {
            DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
            dataSourceTransactionManager.setDataSource(dataSource);
            return dataSourceTransactionManager;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3,由于我们是使用注解形式传入数据源的,所以我们需要在核心配置类里面也开启注解事务驱动 @EnableTransactionManagement

    然后执行,发现成功
    在这里插入图片描述

    事务相关配置

    在这里插入图片描述

    由于事务不为IO异常进行处理,所以我们可以亲自进行处理
    @Transactional(rollbackFor = {IOException.class})

    事务日志记录

    当我们对于一个事务无论执行成功与否,都必须要求另一个代码执行的时候(好比转账失败的记录也需要录入数据库)时,我们可以在事务注解处定义新的事务来避免不执行@Transactional(propagation = Propagation.REQUIRES_NEW)

    在这里插入图片描述

  • 相关阅读:
    揭开ChatGPT面纱(2):OpenAI主类源码概览
    gitlab runner
    基于 Retina-GAN 的视网膜图像血管分割
    AI重建粒子轨迹,发现新物理学
    四旋翼飞行器控制和路径规划附Matlab代码
    Web3在新加坡,叩开世界的大门
    C++之std::lock_guard和std::unique_lock
    R语言缺失时间序列的填充及合并:补齐时间序列数据中所有缺失的时间索引、使用merge函数合并日期补齐之后的时间序列数据和另外一个时间序列数据(补齐右侧数据)
    ES6中set、map、DOM classList的基础用法
    179基于matlab的2D-VMD处理图像
  • 原文地址:https://blog.csdn.net/qq_52480906/article/details/126427109