Spring5_事务

尚硅谷课堂笔记:

链接: https://pan.baidu.com/s/1BPdI_vDWW2M-1A0okF3Pww 提取码: 2333
视频的代码笔记和资料。

老师笔记中的某些内容不再赘叙

此笔记 针对以上笔记为基础 添加补充

主要目的为针对自己复习学习

Spring事务

image-20220317222609617

atomicity consistency isolation durability

  • 原子性

不可分割 要么都成功 要么都失败

  • 一致性

事务提交前后的数据完整性和状态保持一致

总量守恒

  • 隔离性

多事务操作之间不影响

不考虑隔离性 产生的问题:脏读 幻读 不可重复读

  • 持久性

提交之后 表中的数据真正发生变化

脏读 幻读 不可重复读 的理解

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

假设事务 A 更新了一行数据的值为 A 值,此时事务 B 去查询了一下这行数据的值,看到的值是 A 值

事务 B 拿着刚才查询到的 A 值做各种业务处理。但是,事务 A 突然回滚了事务,导致它刚才功能的 A 值没了,此时那行数据的值回滚为 NULL 值。然后事务 B 紧接着此时再次查询那行数据的值,看到的居然是 NULL 值

说明隔离级别“READ-UNCOMMITTED” 但这个隔离级别太低了,一般数据库不会采用

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

前提:必须要事务 B 提交之后,它修改的值才能被事务 A 读取到,其实这种情况下,就是我们首先避免了脏读的发生

假设缓存页里一条数据原来的值是 A 值,此时事务 A 开启之后,第一次查询这条数据,读取到的就是 A 值

接着事务 B 更新了那行数据的值为 B 值,同时事务 B 立马提交了,然后事务 A 此时还没提交。所以事务 A 是可以读到B

紧接着事务 C 再次更新数据为 C 值,并且提交事务了,此时事务 A 在还没提交的情况下,第三次查询数据,查到的值为 C 值

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

幻读就是你一个事务用一样的 SQL 多次查询,结果每次查询都会发现查到一些之前没看到过的数据

SELECT * FROM table WHERE id > 10

它一开始查询出来了 n 条数据。接着这个时候,别的事务 B往表里插了几条数据,而且事务 B 还提交了,此时多了几行数据。事务 A 此时第二次查询,这次它查询出来了 n+m条数据

​ 幻读,不可重复读 都是现象, 脏读是问题

Spring中 解决通过设置事务隔离级别,解决3个问题。在下面((ioslation:事务隔离级别))

1.注解使用流程

image-20220318113659525

Spring支持声明式事务管理,一般使用注解

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

image-20220318115338539

platfromTransactionManager

<?xml version="1.0" encoding="UTF-8"?>
<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">

    <!-- 组件扫描 -->
    <context:component-scan base-package="com.atguigu"></context:component-scan>

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql:///user_DB?useUnicode=true&amp;characterEncoding=utf8" />
        <property name="username" value="root" />
        <property name="password" value="123456" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    </bean>

    <!-- JdbcTemplate对象 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入dataSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--创建事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源,对那个数据库进行事务管理-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--开启事务注解  就是认识事务的注解-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>

1、在spring配置文件配置事务管理器

2、在spring配置文件,开启事务注解

3、在service类上面(或者service类里面方法上面)添加事务注解

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

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

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

@Service
@Transactional
public class UserService {

2.@Transactional 的属性

tip: idea 中ctrl + p 查看属性

image-20220320103605424

  • 1、propagation: 事务传播行为

    @Transactional(propagation = Propagation.REQUIRED)
    

    举例

    首先这个传播行为是针对于被调用的方法而言的,也就是update方法上设置传播行为

    注意:目前的前提都是update有事务

    image-20220320104741579

    image-20220320105138746

    image-20220320104538988

  • 2、ioslation:事务隔离级别

    @Transactional(isolation = Isolation.REPEATABLE_READ) //MySQL默认就是这个
    

    image-20220320114605305

  • 3、timeout: 超时时间

    @Transactional(timeout = 5) //@Transactional(timeout = -1)
    

    image-20220320132236518

  • 4、readOnly: 是否只读

    image-20220320132352235

  • 5、rollbackFor: 回滚

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

  • 6、noRollbackFor: 不回滚

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

3.纯注解开发

//  @Configuration //配置类
//组件扫描  @ComponentScan(basePackages = "com.atguigu")
//  @EnableTransactionManagement 开启事务
public class TxConfig {

    //创建数据库连接池
    //@Component:表示这是一个组件。IOC会托管这个类的对象。@bean:方法返回的对象交给IOC管理。
    //@bean:表示方法返回的是对象,然后对象交给IOC管理。在配置文件中配置对象要写上注解@Bean
    @Bean
    public DruidDataSource getDruidDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///user_db");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }

    //创建JdbcTemplate对象
    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
        //到ioc容器中根据类型找到dataSource (好比@@Autowired 根据类型做注入)
        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;
    }
}

springboot 又进行了进一步封装

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值