彻底学会Spring事务——概念+具体实现

9 篇文章 0 订阅
2 篇文章 0 订阅

目录

1 声明式事务管理的注解实现

2 Transactional事务的参数配置

2.1 propagation:事务传播行为

2.2 ioslation:事务隔离级别

2.3 timeout:超时时间

2.4 readOnly:是否只读

2.5 rollbackFor:回滚

2.6 noRollbackFor:不回滚

3 声明式事务管理的XML实现

4 声明式事务管理完全注解实现


在 Spring 进行事务管理操作有两种方式:编程式事务管理 和 声明式事务管理

声明式事务管理底层使用AOP原理,有两种实现:

(1)基于注解方式(使用)

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

1 声明式事务管理的注解实现

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

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

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

(1)在 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:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.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)如果把这个注解添加方法上面,为这个方法添加事务。

2 Transactional事务的参数配置

有如下参数:

2.1 propagation:事务传播行为

该参数用于配置当多事务方法直接进行调用时,这个过程中事务是如何进行管理的。

事务方法:对数据库表数据进行变化的操作(不包括查询)。

事务的传播行为有7种:

事务传播行为类型

说明

PROPAGATION_REQUIRED

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择(默认值)

PROPAGATION_SUPPORTS

支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY

使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW

新建事务如果当前存在事务,把当前事务挂起,使用新的事务(无论当前是否有事务,都会创建新的事务)

PROPAGATION_NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER

以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

代码示例:

@Transactional(propagation = Propagation.REQUIRED)

2.2 ioslation:事务隔离级别

三个读问题:脏读、不可重复读、幻(虚)读。

脏读是一个问题,在实际情况下不能出现;但是后两种是一种现象,在某些情况下出现也没有什么问题。

(1)脏读

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

具体描述:事务A修改了表中的一行数据,但没有提交,这时候事务B读取了被事务A修改后的数据,之后事务A因为某种原因回滚,那么事务B读取的数据就是脏的。

(2)不可重复度

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

具体描述:事务A和事务B都读取了表中的一行数据(假设为x),这时事务A修改该数据,将x修改成y,并且提交事务,之后事务B再次读取该行数据发现数据变成了y,即事务B两次读取到的数据不一致。

(3)幻读

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

通过设置事务的隔离性来解决上述问题(或现象),通过ioslation参数可以设置隔离级别。

  1. 读未提交,最差的级别,三个问题都不能解决
  2. 读已提交,解决脏读问题
  3. 可重复读,解决不可重读问题(MySQL默认的隔离级别)
  4. 串行化,解决幻读问题

代码示例:

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)

2.3 timeout:超时时间

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

(2)默认值是 -1 ,设置时间以秒单位进行计算。

2.4 readOnly:是否只读

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

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

(3)设置 readOnly 值是 true,设置成 true 之后,只能查询。

2.5 rollbackFor:回滚

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

2.6 noRollbackFor:不回滚

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

3 声明式事务管理的XML实现

在 spring 的xml配置文件中进行配置:

(1)第一步 配置事务管理器

(2)第二步 配置通知

(3)第三步 配置切入点和切面

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

<!--2 配置通知-->
<tx:advice id="txadvice">
    <!--配置事务参数-->
    <tx:attributes>
        <!--指定哪种规则的方法上面添加事务-->
        <tx:method name="accountMoney" propagation="REQUIRED"/>
        <!--<tx:method name="account*"/>-->
    </tx:attributes>
</tx:advice>

<!--3 配置切入点和切面-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="pt" expression="execution(* com.atguigu.spring5.service.UserService.*(..))"/>

<!--配置切面-->
<aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
</aop:config>

4 声明式事务管理完全注解实现

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

@Configuration //配置类
@ComponentScan(basePackages = "com.atguigu") //组件扫描
@EnableTransactionManagement //开启事务
public class TxConfig {
//创建数据库连接池
@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
    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;
}
}

参考链接:https://www.bilibili.com/video/BV1Vf4y127N5?p=40

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值