spring-操作事务

事务概念:

  1. 什么事务
    ​ (1)事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败。
    ​ (2)典型场景: 银行转账,转钱的时候有一个环节失败则两个人的账户不会多钱也不会少钱,只有同时成功才可以
  2. 事务四个特性(ACID)
    (1)原子性
    (2)一致性
    (3)隔离性
    (4)持久性

1. 事务操作(搭建事务操作环境)

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

在这里插入图片描述
2. 创建service,搭建dao,完成对象

@Repository
public class UserDaoImpi implements UserDao{
    
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    //张三给李四转账100
    @Override
    public void reduceMoney() {
    
    
        String sql="update account set money=money-? where username=?";
        int update = jdbcTemplate.update(sql, 100, "张三");
    }
    @Override
    public void addMoney() {
    
    
        String sql="update account set money=money+? where username=?";
        int update = jdbcTemplate.update(sql, 100, "李四");
    }
}

2. 事务操作(搭建事务: )

问题:出现这种情况,当一方转账的时候出现异常,另一方则不会执行,这时候转账的人钱变少了,而另一个人钱不会变多。
在这里插入图片描述

(1)如何解决上面的问题呢?
(2)事务操作过程
在这里插入图片描述

3. 事务操作(spring事务管理介绍)

  1. 事务添加到JavaEE三层结构里面的service层(业务逻辑层)

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

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

  3. 声明事务管理

    (1)基于注解方式实现

    (2)基于xml配置文件方式实现

  4. 在spring进行声明式事务管理,底层使AOP原理

  5. Spring事务管理API

    (1)提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类
    在这里插入图片描述

事务管理(注解声明式事务管理)

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

    (1)在spring配置文件中引入名称空间tx

xmlns:tx="http://www.springframework.org/schema/tx"
  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>
  1. 在service类上面(或者service类里面方法上面)添加事务注解
    (1)@Transational,这个注解添加到类上面,也可以添加到方法上面

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

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

@Service
@Transactional
public class UserService {
    
    

运行结果:

虽然出现了异常,但是进行了事务的回滚,数据库中的转账金额并没有发生变化

4. 事务操作(声明式事务管理参数配置)

在这里插入图片描述

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

  2. propagation:事务传播行为

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

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

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

  1. iosation:事务隔离级别

    (1)事务特性成为隔离性,多事务操作之间不会产生影响。不考虑隔离性则会产生很多问题

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

    (3)脏读:一个未提交事务读取到另一个未提交的事务的数据

在这里插入图片描述

(4)不可重复读:一个未提交事务读取到另一个提交事务修改数据

在这里插入图片描述

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

(6)解决:通过设置事务隔离性,解决读的问题

在这里插入图片描述
在这里插入图片描述

  1. timeout:超时时间

    (1)事务需要在一定的时间内需要提交,如果不提交就回滚

    (2)默认值是-1,设置时间是以秒进行计算
    在这里插入图片描述

  2. readOnly:是否只读

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

    (2)readOnly默认值false,表示可以查询,可以添加修改删除操作

    (3)readOnly为True时,只能进行查询操作。
    在这里插入图片描述

  3. rollbackFor:回滚

    (1)出现哪些事务的异常进行回滚

  4. noRollbackFor:不回滚

    (2)出现哪些事务的异常不进行回滚

5. 事务操作(XML声明式事务方管理方式)

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

    第一步 配置事务管理器

    第二步 配置通知

    第三步 配置切入点和切面

    <!--    2.配置通知-->
            <tx:advice id="txAdvice">
    <!--            配置参数-->
                <tx:attributes>
                    <tx:method name="accountMoney" propagation="REQUIRED"/>
    <!--                表示以account开头的都可以-->
                    <tx:method name="account*"/>
                </tx:attributes>
            </tx:advice>
    <!--        3.配置切入点和切面-->
            <aop:config>
    <!--            配置切入点-->
                <aop:pointcut id="pt" expression="execution(* com.study.service.UserService.*(..))"/>
    <!--            配置切面-->
                <aop:advisor advice-ref="txAdvice" pointcut-ref="pt" />
            </aop:config>
    

6. 事务操作(完全注解声明式事务管理)

  1. 创建配置类,使用配置类替代xml配置文件
@Configuration //配置类
@ComponentScan(basePackages = "com.study") //组件扫描
@EnableTransactionManagement //开启事务
public class TxConfig {
    
    
    //创建数据库连接池
    @Bean
    public DruidDataSource getDruidDataSource() {
    
    
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/user");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        return dataSource;
    }
    //创建JdbcTemplate对象
    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
    
    
        //到ioc容器中根据类型找到dataSource
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        //注入dataSource
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }
//    创建事务管理器
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {
    
    
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_14930709/article/details/124561773