Spring学习笔记【十四】事务处理

事务处理

01 概念

1、保证业务操作完整性的一种数据库机制
2、事务的四个特点:A C I D

  • A :原子性
  • C :一致性
  • I :隔离性
  • D : 持久性

02 如何来控制事务

普通的事务控制底层,都是使用Connection对象来完成的

2.1 使用 jdbc 如何处理事务

  • Connection.setAutoCommit(false);
  • Connection.commit();
  • Connection.rollback();

2.2 使用mybatis处理事务

Mybatis 会自动提交事务

  • SqlSession(Connection).commit();
  • SqlSession(Connection).rollback();

03 Spring控制事务的开发

:::success
Spring是通过AOP的方式进行事务的开发
:::

3.1 分析

3.1.1 原始对象
public XXXUserServiceImpl implements UserService{
	private XXXUserMapper usermapper;
}

3.1.2 额外功能
方式一:实现MetnodIntercepetor 接口
public Object invoke(MethodInvocation invocation){
	try{
    	Connection.setAutoCommit(false);
    	Object ret = invocation.proceed();
        Connection.commit();
    	return ret;
    }catch(Exception e){
    	Connection.rollback();
    }	
}

方式二:@Aspect


Spring提供:org.springframework.jdbc.datasource.DataSourceTransactionManager
	注入连接,注入连接池对象

3.1.3 切入点

:::success
@Transactional:事务的额外功能加给那些业务方法
:::

  • 类上:类上所有的方法都会加入事务
  • 方法上:这个方法会加上事务
3.1.4 组装切面
  1. 切入点
  2. 额外功能

<tx:annotation-driven transaction-manager=""/>

3.2 编码

3.2.1 搭建开发环境
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-tx</artifactId>
  <version>5.3.9</version>
</dependency>

3.2.2 原始对象
@Data
public class UserServiceImpl implements UserService {
    private UserMapper userMapper;
    @Override
    public void register(User user) {
        userMapper.register(user);
    }
}

3.2.3 额外功能
   <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource"/>
   </bean>

3.2.4 切入点

加入注解

@Data
@Transactional
public class UserServiceImpl implements UserService {
    private UserMapper userMapper;
    @Override
    public void register(User user) {
        userMapper.register(user);
    }
}

3.2.5 组装切面
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"></tx:annotation-driven>

3.3 细节分析

  • 进行动态代理底层实现的切换
  • 默认值为false,底层是JDK
  • 如果说指定位true,底层就是Cglib
   <tx:annotation-driven transaction-manager="dataSourceTransactionManager" proxy-target-class="false" />

04 Spring中的事务属性

4.1 什么是事务属性

:::info
属性:描述物体特征的一系列值
性别,身高,体重。。。。。
事务属性:描述事务特征的一系列值
:::

  • 隔离属性
  • 传播属性
  • 只读属性
  • 超时属性
  • 异常属性

4.2 如何添加事务属性

@Transactional(isloation=对应的值)

4.3 隔离属性

4.3.1 隔离属性的概念
  • 描述了事务解决并发问题的特征
  • 什么是并发:多个事务(用户)在同一时间,访问操作了相同的数据
  • 并发会产生什么问题
    • 脏读
    • 不可重复读
    • 幻影读
  • 并发问题如何解决:通过隔离属性解决,隔离属性中设置不同的值,解决并发处理过程中的问题
4.3.2 脏读
  1. 一个事务,读取了另一个事务中没有提交的数据,会在本事务中产生数据不一致的问题
  2. @Transactional(isolation = Isolation._READ_COMMITTED_)
4.2.3 不可重复读
  1. 一个事务中,多次读取相同的数据,但是读取的结果不一致,会在本事务中产生数据不一致的问题
  2. 本质是一把行锁
  3. @Transactional(isolation = Isolation._REPEATABLE_READ_)
4.2.4 幻影读
  1. 一个事务中,多次对整表进行查询统计,但是结果不一致,会在本事务中产生数据不一致的问题
  2. @Transactional(isolation = Isolation._SERIALIZABLE_)
  3. 本质是表锁
4.2.5 总结
  1. 并发安全:SERIALIZABLE > REPEATABLE_READ > READ_COMMITTED
  2. 运行效率:SERIALIZABLE < REPEATABLE_READ < READ_COMMITTED
  3. ISOLATION_DEFAULT:会调用不同数据库所设置的默认隔离属性
    1. MYSQL:REPEATABLE_READ
    2. Oracle:READ_COMMITTED
4.2.6 数据库对隔离属性的支持
隔离属性的值MySQLOracle
Isolation._READ_COMMITTED_支持支持
Isolation._REPEATABLE_READ_支持不支持(采取多版本对比的方式)
Isolation._SERIALIZABLE_支持支持

4.2.7 实战建议
  1. 推荐使用Spring指定的ISOLATION_DEFAULT
  2. 未来中的实战中,并发访问情况很低
  3. 如果说真遇见并发问题,使用乐观锁

4.4 传播属性

4.4.1 概念
  1. 描述了事务解决嵌套问题的特征
    1. 事务嵌套:指的是一个大的事务中,包含一个小的事务
  2. 问题:大事务中融入了很多小的事务,他们彼此影响,最终就会导致外部大的事务,丧失了事务的原子性
4.4.2 传播属性的值及其用法

REQUIRED

  • 传播属性的默认值
  • 外部不存在事务:开启新的事务
  • 外部存在事务:融合到外部事务中
  • 用法:@Transactional(propagation = Propagation._REQUIRED_)
  • 主要用于增删改方法之中,可以不进行书写,本身就是默认值

SUPPORTS

  • 外部不存在事务:不开启新的事务
  • 外部存在事务:融合到外部事务中
  • 用法:@Transactional(propagation = Propagation._SUPPORTS_)
  • 主要运行在查询方法之中

REQUIRES_NEW

  • 外部不存在事务:开启新的事务
  • 外部存在事务:挂起外部事务,创建新的事务
  • 用法:@Transactional(propagation = Propagation._REQUIRES_NEW_)
  • 主要用于日志记录的方法之中

NOT_SUPPORTED

  • 外部不存在事务:不开启新的事务
  • 外部存在事务:挂起外部事务
  • 用法:@Transactional(propagation = Propagation._NOT_SUPPORTED_)
  • 不常用

NEVER

  • 外部不存在事务:不开启事务
  • 外部存在事务:抛出异常
  • 用法:@Transactional(propagation = Propagation._NEVER_)
  • 不常用

MANDATORY

  • 外部不存在事务:抛出异常
  • 外部存在事务:融合到外部事务中
  • 用法:@Transactional(propagation = Propagation._MANDATORY_)
  • 不常用

4.5 只读属性

针对于只进行查询操作的业务方法,可以加入只读属性,提高运行效率,默认值为 false
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)

4.6 超时属性

  1. 概念:制定了事务等待的最长时间
  2. 为什么事务要进行等待?
  • 因为当前事务访问数据的时候,有可能访问的数据被别的事务进行加锁操作,所以本事务就必须进行等待
  1. 默认值是 -1,最终是由对应的数据库来进行指定;一般情况之下用默认值就行
@Transactional(timeout = 2)

4.7 异常属性

  1. Spring的事务过程中,默认对于RuntimeException 及其子类,采用的是回滚策略
    1. @Transactional(noRollbackFor = {java.lang.RuntimeException.class}
  2. Spring的事务过程中,默认对于Exception及其子类,采用的提交策略
    1. @Transactional(rollbackFor = {java.lang.Exception.class})

4.8 事务属性常见配置总结

  1. 隔离属性: 默认值
  2. 传播属性: Required(默认值)增删改、Supports 查询操作
  3. 只读属性: readOnly=false 增删改,true 查询操作
  4. 超时属性: 默认值 -1
  5. 异常属性: 默认值
1. 增删改操作:@Transactional
2. 查询操作:@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)

05 基于标签的事务配置方式

5.1 基本使用

一般情况之下,切入点写成包切入点

<!--事务属性-->
    <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
        <tx:attributes>
            <tx:method name="register" isolation="READ_COMMITTED" propagation="MANDATORY"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="pc" expression="execution(* com.spring3.service.UserService.register(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/>
    </aop:config>

5.2 实战应用方式

  • 方式一:所有以Service结尾的方法名
<tx:attributes>
    <tx:method name="*Service"/>
</tx:attributes>
  • 方法二:除了以Service方法结尾的其余方法
<tx:attributes>
       <tx:method name="*Service"/>
       <tx:method name="*"/>
</tx:attributes>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

佩奇inging

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值