事务

一、概念
  1. 什么是事务
    • 事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败
    • 典型场景:银行转账
  2. 事务四个特性(ACID)
    1. 原子性
    2. 一致性
    3. 隔离性
    4. 持久性
二、搭建事务操作环境
  1. 创建数据库表,添加记录

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tzWT9Emj-1621685189633)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210522172744507.png)]

  2. 创建service,搭建dao,完成对象创建和注入关系

    1. service注入dao,在dao注入JdbcTemplate,在JdbcTemplate注入DataSource

      @Service
      public class AccountService {
          @Autowired
          private AccountDao accountDao;
      
          public void accountMoney(){
              accountDao.reduceMoney();
              accountDao.addMoney();
          }
      }
      
      @Repository
      public class AccountDaoImpl implements AccountDao {
          @Autowired
          private JdbcTemplate jdbcTemplate;
          @Override
          public void addMoney() {
              String sql = "update tb_account set money = money+? where name= ?";
              jdbcTemplate.update(sql,100,"mary");
          }
      
          @Override
          public void reduceMoney() {
              String sql = "update tb_account set money = money-? where name= ?";
              jdbcTemplate.update(sql,100,"lucy");
          }
      }
      
    2. 测试类

      @Test
      public void accountMoney() {
          ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
          AccountService accountService = context.getBean("accountService", AccountService.class);
          accountService.accountMoney();
      }
      
    3. 上面代码,如果正常执行没有问题,但是如果代码执行过程中出现异常,就会出现问题

      例如:

      public void accountMoney(){
          accountDao.reduceMoney();
          int i = 10/0;
          accountDao.addMoney();
      }
      
      1. 如何处理以上异常
      2. 事务操作过程
        • 开启事务
        • 进行业务操作
        • 没发生异常提交事务
        • 出现异常回滚事务
三、事务操作(Spring事务管理介绍)
  1. 事务添加到JavaEE三层结构里面Service层(业务逻辑层)

  2. 在Spring进行事务管理操作

    有两种方式:编程式事务管理和声明事务管理(使用)

  3. 声明式事务管理

    1. 基于注解方式(使用)
    2. 基于xml配置文件方式
  4. 在Spring进行声明式事务管理,底层使用AOP原理

  5. Spring事务管理API

    1. 提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类
四、事务操作(注解声明式事务管理)
  1. 在Spring配置文件配置事务管理器

    <bean id="DataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
  2. 在Spring配置文件,开启事务注解

    1. 在spring配置文件引入名称空间

      <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
      ">
      
    2. 开启事务注解

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

      1. @Transactional,这个注解添加到类上面,也可以添加到方法上面

      2. 如果把这个注解添加到类上面,这个类里面所有的方法都添加事务

      3. 如果把这个注解添加方法上面,为这个方法添加事务

        @Service
        @Transactional
        public class AccountService {
            @Autowired
            private AccountDao accountDao;
        
            public void accountMoney(){
                accountDao.reduceMoney();
                int i = 10/0;
                accountDao.addMoney();
            }
        }
        
五、事务操作(声明式事务管理参数配置)
  1. 在service类上面添加注解@Transactional,在这个注解里面可以配置事务相关参数

  2. propagation:事务传播行为

    1. 多事务方法直接进行调用,这个过程中事务是如何进行管理的

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

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bX7wiBSF-1621685189637)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210522192539667.png)]

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cin3na2d-1621685189640)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210522192447660.png)]

  3. ioslation:事务隔离级别

    1. 事务有特性成为隔离性,多事务操作之间部会产生影响。不考虑隔离新产生很多问题
    2. 有三个读问题:脏读、不可重复读、虚(幻)读
    3. 脏读:一个未提交事务读取到另一个未提交事务的数据
    4. 不可重复读:一个未提交事务读取到另一提交事务修改数据
    5. 虚读:一个未提交事务读取到另一提交事务添加数据
    6. 通过设置事务隔离级别,解决读的问题
  4. timeout:超时时间

    1. 事务需要在一定的时间内进行提交,如果不提交进行回滚
    2. 默认值是-1,设置时间以秒为单位进行计算
  5. readOnly:是否只读

    1. 读:查询操作,写:添加修改删除
    2. readOnly默认值false,表示可以查询,可以添加修改删除操作
    3. 设置readOnly值是true,设置成true之后,只能查询
  6. rollbackFor:回滚

    1. 设置出现哪些异常进行事务回滚
  7. noRollbackFor:不回滚

    1. 出现哪些异常不进行事务回滚
六、事务操作(XML声明式事务管理)
  1. 在spring配置文件中进行配置

    第一步配置事务管理器

    第二步配置通知

    第三步配置切入点和切面

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>
    <!--    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>-->
        <tx:advice id="txadvice">
            <tx:attributes>
                <tx:method name="accountService" propagation="REQUIRED"/>
            </tx:attributes>
        </tx:advice>
        <aop:config>
            <aop:pointcut id="pt" expression="execution(* com.gdcp.service.AccountService.*(..))"/>
            <aop:advisor advice-ref="txadvice" pointcut-ref="pt" ></aop:advisor>
        </aop:config>
    
七、事务操作(完全注解声明式事务管理)
  1. 创建配置类,使用配置类替代xml配置文件

    package com.gdcp.config;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    import javax.sql.DataSource;
    
    
    @Configuration
    @ComponentScan(basePackages = {"com.gdcp"})
    @EnableTransactionManagement
    public class TxConfig {
        @Bean
        public DruidDataSource getDruidDataSource(){
            DruidDataSource druidDataSource = new DruidDataSource();
            druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
            druidDataSource.setUrl("jdbc:mysql:///user_db");
            druidDataSource.setUsername("root");
            druidDataSource.setPassword("root");
            return druidDataSource;
        }
    
        @Bean
        public JdbcTemplate getJdbcTemplate(DataSource dataSource){
            JdbcTemplate jdbcTemplate = new JdbcTemplate();
            jdbcTemplate.setDataSource(dataSource);
            return jdbcTemplate;
        }
    
        @Bean
        public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
            DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
            dataSourceTransactionManager.setDataSource(dataSource);
            return dataSourceTransactionManager;
        }
    }
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值