栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

Spring5中的事务管理

Java 更新时间:发布时间: 百科书网 趣学号
Spring5中的事务管理

事务在之前就已经了解过了,这里简单的来讲一下,在一条或多条DML语句执行时,确保同时成功或者同时失败

模型搭建

举一个非常典型的问题,银行转账问题,Jerry向Tom转账100元,其中一共产生两条sql语句,第一Jerry余额少100,第二Tom余额多100,且必须要保证这两条语句要么同时成功要么同时失败。

之前在JavaWeb中解决办法是关闭当前数据库连接的自动提交,在成功的时候提交,失败的时候回滚。来看一下Spring5中该如何处理

首先我们先搭建上述问题的模型

  • 数据库模型搭建

    做的非常简单,只需要用户名和余额即可

  • Service及Dao

    @Service
    public class BankService {
        @Autowired
        public BankDaoImpl bankDao;
    
        public void accountMoney(){
            bankDao.addMoney();
            //模拟异常
            int i = 10/0;
            bankDao.removeMoney();
        }
    
        public void setBankDao(BankDaoImpl bankDao) {
            this.bankDao = bankDao;
        }
    }
    
    @Repository
    public class BankDaoImpl implements BankDao {
        @Autowired
        public JdbcTemplate jdbcTemplate;
    
        @Override
        public void addMoney() {
            String sql = "update t_bank set `balance` = balance + 100 where id = 1";
            jdbcTemplate.execute(sql);
        }
    
        @Override
        public void removeMoney() {
            String sql = "update t_bank set `balance` = balance - 100 where id = 2";
            jdbcTemplate.execute(sql);
        }
    
        public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
            this.jdbcTemplate = jdbcTemplate;
        }
    }
    
  • xml配置文件

    
    
        
        
    
        
        
            
            
            
            
        
    
        
        
            
        
    
    
  • 测试类

        @Test
        public void test3(){
            ApplicationContext context = new ClassPathXmlApplicationContext("Bean.xml");
            BankService bankService = context.getBean("bankService", BankService.class);
            bankService.accountMoney();
        }
    

Spring5事务管理介绍
  • 事务添加到Java EE三层架构中的Service层(业务逻辑层)
  • 在Spring进行事务管理操作有两种方式
    • 编程式事务管理(即上文所讲的成功提交,失败回滚)
    • 声明式事务管理
      • 基于注解方式(推荐使用)
      • 基于XML配置文件方式
  • 在Spring进行声明式事务管理,底层使用AOP原理

使用Spring管理事务
  1. 在xml文件中配置事务管理器并注入数据源

        
        
            
            
        
    
  2. 开启事务注解

        需要在头部文件配置tx空间
    	
        
    
  3. 在方法或类上添加@Transactional注解

    在方法上添加代表对此方法进行事务管理,在类上添加代表对类中的所有方法进行事务管理

    @Service
    @Transactional
    public class BankService {
        @Autowired
        private BankDaoImpl bankDao;
    
        public void accountMoney(){
            bankDao.addMoney();
            //模拟异常
            int i = 10/0;
            bankDao.removeMoney();
        }
    
        public void setBankDao(BankDaoImpl bankDao) {
            this.bankDao = bankDao;
        }
    }
    

Spring事务管理:事务参数

先来看一下几个比较重要的事务参数

  • propagation:传播行为
  • isolation:隔离级别
  • timeout:存活时长:事务在一定时间内进行提交,不提交则回滚
  • readOnly:只读:设置true代表数据库只读,只能进行查询操作
  • rollbackFor:回滚:出现哪些异常进行回滚
  • noRollbackFor:不回滚:出现哪些异常不回滚

传播行为

spring定义了7种事务传播行为,最常用的是REQUIRED或REQUIRED_NEW

  • REQUIRED:如果有事务在运行,当前的方法就在这个事务内运行,否则启动一个新事务,并在自己的事务内运行(默认)
  • REQUIRED_NEW:当前方法必须启动新事务,并在自己的事务内运行,如果有事务正在运行,应该将他挂起
  • SUPPORTS:如果有事务在运行,当前的方法就在这个事务内运行,否则它可以不运行在事务中
  • NOT_SUOPPORTS:当前的方法不应该运行在事务中,如果有运行的事务,将他挂起
  • MANDATORY:当前的方法必须运行在事务中,如果没有正在运行的事务,就抛出异常
  • NEVER:当前方法不应该运行在事务中,如果有运行的事务,就抛出异常
  • NESTED:如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则就启动一个新的事务,并在他自己的事务内运行
@Service
@Transactional(propagation = Propagation.REQUIRED)
public class BankService {

隔离级别

事务的隔离级别分四种

  • 读未提交
  • 读已提交
  • 可重复读
  • 序列化读
@Service
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
public class BankService {

完全注解开发

创建配置类,代替xml配置文件

  1. 创建配置类
  2. 开启注解扫描
  3. 开启事务
  4. 创建数据库连接池
  5. 创建JdbcTemplate对象
  6. 创建事务管理器
@Configuration //配置类
@ComponentScan(basePackages = "com.yellowstar") //组件扫描
@EnableTransactionManagement //开启事务
public class TransactionConfig {
    //创建数据库连接池对象
    @Bean
    public DruidDataSource getDruidDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true");
        dataSource.setUsername("root");
        dataSource.setPassword("Hkx123");
        return dataSource;
    }

    //创建JdbcTemplate对象
    @Bean
    public JdbcTemplate getJdbcTemplate(DruidDataSource dataSource){
        //到 ioc 容器中根据类型找到 dataSource
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

    //创建事务管理器
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DruidDataSource dataSource){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }
}
转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/295287.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号