Spring 事务操作

事务操作

概念

什么是事务

  1. 事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败,所有操作都失败
  2. 典型场景:银行转账

事务四个特性(ACID):

  1. 原子性:不可分割
  2. 一致性:总量不变
  3. 隔离性:两个人同时操作,不会对彼此产生影响
  4. 持久性:提交后表中数据发生真正变化

搭建环境

image-20201009080706605

  1. 创建数据库表,添加记录image-20201009081205336

  2. 创建service,搭建dao,完成对象的创建和注入。

    • service注入dao
    • dao注入jdbctemplate,在JDBCTemplate注入dataSource
    • 在dao创建两个方法,多钱和少钱,在service创建转账方法
    • 问题,在有异常时一半的方法执行

事务操作过程

        try {
            userDao.reduceMoney();
//        模拟异常
            int i = 1 / 0;
            userDao.addMoney();
            //没有发生异常,事务提交
        } catch (Exception e) {
            //出现了异常,事务回滚
            e.printStackTrace();
        }

Spring事务管理介绍

  1. 事务一般添加在javaee三层结构里的Service层
  2. 在Spring进行事务管理操作有两种方式
    • 编程式事务管理
    • 声明式事务管理(使用)基于注解方式,基于xml配置文件方式

声明式事务管理

Spring进行声明式事务管理,底层使用AOP

Spring事务管理API

​ 1. 提供了一个接口,代表事务管理器,这个接口针对不同的框架提供了不同的实现类image-20201009091817397

注解方式实现声明式事务管理

  1. 在Spring配置文件中配置事务管理器

    <!--    配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
  2. 在spring配置文件中开启事务注解

    • 在spring配置文件中引入名称空间tx

      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context.xsd
             http://www.springframework.org/schema/tx
             http://www.springframework.org/schema/tx/spring-tx.xsd">
      
    • 开启事务

      <!--    开启事务注解-->
      <tx:annotation-driven transaction-manager="transactionManager"/>
      
  3. 在Service类上面(或者service类方法上面)添加事务注解

    • @Transactional 加在类和方法上均可

    • 如果添加在类上面,代表类里面的所有方法都添加了事务

    • 如果放在方法上面,只是为这个方法添加事务

      @Service(value = "userServiceImpl")
      @Transactional //加在类和方法上均可
      public class UserServiceImpl implements UserService {
          @Autowired
          @Qualifier("userDaoImpl")
          private UserDao userDao;
      
          public void accountMoney() {
              userDao.reduceMoney();
              int i = 1 / 0;
              userDao.addMoney();
      
          }
      }
      

声明式事务管理参数配置

  1. 在service类上面添加注解@Transactional,在这个注解里面可以配置事务相关参数 image-20201009103159623

  2. propagation:事务传播行为

    多事务方法之间执行调用,这个过程中事务是如何进行管理的

    事务方法:对数据库表进行变化的操作

    七种传播行为

    image-20201009104240840

  3. isolation:事务的隔离级别

    事务有特性:隔离性,多事务操作之间不会产生影响。不考虑隔离性会产生很多问题

    有三个读的问题,脏读,不可重复读,虚(幻)读

    脏读:一个未提交事务读取到另一个未提交事务的数据image-20201009113614835

    不可重复读:一个未提交事务读取到一个提交事务修改数据image-20201009113939287

    虚读:一个未提交事务读取到另一提交事务添加数据

    通过设置事务隔离级别,就能解决三个读的问题image-20201009114356882

    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ) 
    
  4. timeout超时时间。

    事务需要在一定时间内进行提交,如果不提交,就会回滚

    默认值是-1,设置时间以秒(s)为单位

  5. readonly:是否只读

    读:查询操作,写:添加修改删除

    readOnly默认为false

    设置为true后,只能查询

  6. rollbackfor,回滚

    设置出现哪些异常进行事务回滚

  7. norollbackfor:不回滚

    设置出现哪些异常不进行回滚

XML声明式事务管理

  1. 在Spring配置文件中进行配置

    第一步:配置事务管理器

    第二步:配置通知

    第三步:配置切入点和切面

    <!--    配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--    配置通知-->
    <tx:advice id="txadvice">
        <!--        配置事务相关参数-->
        <tx:attributes>
            <!--            指定在哪种规则的方法上添加事务-->
            <tx:method name="accountMoney" propagation="REQUIRED"/>
            <!--            <tx:method name="account*"/>-->
        </tx:attributes>
    </tx:advice>
    
    <!--    配置切入点和切面-->
    <aop:config>
        <!--        配置切入点-->
        <aop:pointcut id="pt" expression="execution(* com.yang.service.UserServiceImpl.*(..))"/>
        <!--        配置切面-->
        <aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
    </aop:config>
    

完全注解开发

  1. 创建配置类,使用配置类替代xml配置文件

    @Configuration
    @ComponentScan(basePackages = "com.yang")
    @EnableTransactionManagement //开启事务
    public class TxConfig {
        //创建数据库连接池
        @Bean
        public DruidDataSource dataSource() {
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql://localhost:3306/mybatis?useSSL=true&serverTimezone=Asia/Shanghai&CharacterEncoding=utf-8");
            dataSource.setUsername("root");
            dataSource.setPassword("123456");
            return dataSource;
        }
    
        //创建jdbcTemplate模板对象
        @Bean
        public JdbcTemplate jdbcTemplate(DataSource dataSource) {
            //到ioc容器中根据类型找到dataSource
            JdbcTemplate jdbcTemplate = new JdbcTemplate();
            jdbcTemplate.setDataSource(dataSource);
            return jdbcTemplate;
        }
    
        //创建事务管理器
        @Bean
        public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource) {
            DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
            dataSourceTransactionManager.setDataSource(dataSource);
            return dataSourceTransactionManager;
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值