Spring5学习随笔-事务属性详解(@Transactional)

这篇具有很好参考价值的文章主要介绍了Spring5学习随笔-事务属性详解(@Transactional)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

学习视频:【孙哥说Spring5:从设计模式到基本应用到应用级底层分析,一次深入浅出的Spring全探索。学不会Spring?只因你未遇见孙哥】

第三章、Spring的事务处理

1.什么是事务?

事务是保证业务操作完整性的一种数据库机制
事务的4特点:ACID

  1. A 原子性
  2. C 一致性
  3. I 隔离性
  4. D 持久性

2.如何控制事务

JDBC:

Connection.setAutoCommit(false)

Connection.commit();

Connection.rollback();

Mybatis:

Mybatis自动开启事务

SqlSession(底层还是Connection).commit();

sqlSession(底层还是Connection).rollback();

结论:控制事务的底层 都是Connection对象完成的

3.Spring控制事务的开发

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

  1. 原始对象

    public class XXXUserServiceImpl{
    	1.原始对象 ---> 原始方法  --->核心功能(业务处理+DAO调用)
    	2.DAO作为Service的成员变量,依赖注入的方式进行赋值
    }
    
  2. 额外功能

    下面的额外功能封装在org.springframework.jdbc.datasource.**DataSourceTransactionManager
    应用的过程需要注入DataSource**
    
    1.MethodInterceptor
    public Object invoke(MethodInvocation invocation){
    	try{
    		Connection.setAutoCommit(false);
    		Object ret = invocation.proceed();
    		Connection.commit();
    		return ret;
    	}catch(Exception e){
    		Connection.rollback();
    	}
    }
    2. @Aspect
    	 @Around
    
  3. 切入点

    @**Transactional**
    事务的额外功能能加入给那些业务方法
    
    1. 类上:类中所有的方法都会加入事务
    2. 方法上:这个方法加入事务
    
  4. 组装切面

    1. 切入点
    2. 额外功能

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

4.Spring控制事务的编码

  • 搭建开发环境(jar)
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.1.14.RELEASE</version>
</dependency>
  • 编码
<!-- 1. 原始对象-->
<bean id="userService" class="com.baizhi.service.UserServiceImpl">
    <property name="userDao" ref="userDao"/>
</bean>
<!-- 2. 额外功能-->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

3.切入点
@Transactional
public class UserServiceImpl implements UserService {
    private UserDao userDao;
<!--
    4.组装
    选择结尾是/tx的driven
-->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
  • 细节

    <tx:annotation-driven transaction-manager="dataSourceTransactionManager" proxy-target-class="true"/>

    进行动态代理底层实现的切换 proxy-target-class

    默认false:JDK true: Cglib

第四章、Spring中的事务属性(Transaction Attribute)

1.什么是事务属性

属性:描述物体特征的一系列值

性别 身高 体重…

所谓的事务属性指的是描述事务特征的一系列值

  1. 隔离属性
  2. 传播属性
  3. 只读属性
  4. 超时属性
  5. 异常属性

2.如何添加事务属性

@Transactional(isolation(隔离属性)=,propagation(传播属性)=,readOnly(只读属性)=,timeout(超时属性)=,rollbackFor=,noRollbackFor=);

3.事务属性详解

1.隔离属性(ISOLATION)

  • 隔离属性的概念

    概念:他描述了事务解决并发问题的特征

    1. 什么是并发

      指的是多个事务(用户)在同一时间,访问操作了相同的数据

      重点 同一时间:微小的时间内 0.0000几秒 微小前、后

    2. 并发会产生那些问题

      1. 脏读
      2. 不可重复读
      3. 幻影读
    3. 并发问题如何解决

      通过隔离属性解决,隔离属性设置不同的值,解决并发处理过程中的问题。

  • 事务并发产生的问题

    • 脏读

      指的是一个事务/用户读取了另外一个事务/用户中没有提交的数据。会在本事务中产生不一致的问题

      解决方案:@Transactional(isolation=Isolation.READ.COMMITTED)

      本质:只读取已提交的数据

    • 不可重复读

      一个事务中,多次读取相同的数据,但是读取结果不一样,会在本事务中产生数据不一致的问题

      注意:1.不是脏读 2.在一个事务中

      解决方案:@Transactional(isolation=Isolation.REPEATABLE_READ)

      本质:对应数据库底层的行锁(第一个人在读取数据时,其他人都得等第一个人处理完)

    • 幻影读

      一个事务中,多次对整表进行查询统计,但是结果不一样,会在本事务中产生数据不一致的问题。

      解决方案:@Transactional(isolation=Isolation.SERIALIZABLE)

      本质对应数据库底层的表锁

    • 总结

      并发安全:SERIALIZABLE>REPEATABLE_READ>READ.COMMITTED

      运行效率:READ.COMMITTED>REPEATABLE_READ>SERIALIZABLE

  • 数据库对于隔离属性的支持

    隔离属性的值 MySQL Oracle
    Isolation.READ.COMMITTED ✔️ ✔️
    Isolation.REPEATABLE_READ ✔️
    Isolation.SERIALIZABLE ✔️ ✔️

    Oracle不支持REPETABLE_READ值 采用的是多版本比对的方式 解决不可重复读的问题

  • 默认隔离属性

    ISOLATION_DEFAULT:会调用不同数据库所设置的默认隔离属性

    例如:如果使用MYSQL 默认隔离属性:REPEATABLE_READ,Oracle:READ_COMMITTED

    • 查看数据库默认隔离属性
      • MySQL

        8.0版本以前:select @@tx_isolation
        8.0版本之后:select @@transaction_isolatio
        
  • 隔离属性在实战中的建议

    推荐使用Spring指定的ISOLATION——DEFALUT

    1. MySQL repeatbale_read
    2. Oracle READ_COMMITED

    未来中的实战中,并发访问情况 很低(前提就是海量用户

    如果真遇到并发问题,可以使用乐观锁

    Hibernate(JPA) Version

    MyBatis 通过拦截器自定义开发

2.传播属性(PROPAGATION)

  • 传播属性的概念

    概念:他描述了事务解决嵌套问题的特征

    什么叫做事物的嵌套:他指的是一个大的事务中,包含若干个小的事务

    问题:大事务中融入了很多小的事务,他们彼此影响,最终导致外部大的事务,丧失了事务的原子性

  • 传播属性的值及其用法

    不管属性是什么,其中心思想是保证同一时间只会有一个事务的存在

    传播属性的值 外部不存在事务 外部存在事务 用法 备注
    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 极其不常用

融合指的是:放弃自己的事务,以外部的事务为准

  • 默认的传播属性

    REQUIRED是传播属性的默认值

  • 推荐传播属性的使用方式

    增删改 方法:直接使用默认值REQUIRED

    查询 操作:显示指定传播属性的值SUPPORTS

3.只读属性(readOnly)

针对于只进行查询操作的业务方法,可以加入只读属性,提供运行效率

默认值:false

4.超时属性(timeout)

指定了事务等待的最长时间

  1. 为什么事务要进行等待呢?

    因为在当前事务访问数据时,有可能访问的数据是被别的事务进行加锁的处理,那么此时本事务就必须进行等待

  2. 等待时间:秒

  3. 如何应用 @Transactional(timeout=2)

  4. 超时属性的默认值:-1

    最终由对应的数据库来指定默认值,一般使用默认值

5.异常属性

Spring事务处理过程中

默认 对于RuntimeException及其子类 采用的是回滚的策略

默认 对于Exception及其子类 采用的是提交的策略

想要改变默认的策略,可以设置两个属性

  1. rollbackFor(回滚) ={java.lang.Exception,xxx,……};
  2. noRollbackFor(不回滚)=
@Transactional(rollbackFor = {Exception.class},noRollbackFor = {RuntimeException.class})

建议:实战中使用RuntimeException及其子类 使用事务异常属性的默认值,实际开发很少改变策略

4.事务属性常见配置总结

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

后续实战当中的建议:增删改操作 @Transactional

而对于查询操作 @Transactional(propagation=Propagation.SUPPORTS,readOnly=true)

5.基于标签的事务配置方式(事务开发的第二种形式)

  • 基于注解 @Transaction的事务配置回顾
<!-- 1. 原始对象-->
<bean id="userService" class="com.baizhi.service.UserServiceImpl">
    <property name="userDao" ref="userDao"/>
</bean>
<!-- 2. 额外功能-->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

3.切入点
@Transactional
public class UserServiceImpl implements UserService {
    private UserDao userDao;
<!--
    4.组装
    选择结尾是/tx的driven
-->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
  • 基于标签的事务配置
<!-- 1. 原始对象-->
<bean id="userService" class="com.baizhi.service.UserServiceImpl">
    <property name="userDao" ref="userDao"/>
</bean>
<!-- 2. 额外功能-->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<!-- 第三步 事务属性 -->
<tx:advice id="txAdvice" transacation-manager="dataSourceTransactionManager">
		<tx:attributes>
				<tx:method name="register" isolation="DEFAULT" propagation=""/>
				<tx:method name="login"...../>
		</tx:attributes>
</tx:advice>

<!-- 第四步 指定切入点-->
<aop:config>
		<aop:pointcut id="pc" expression="execution(* com.baizhi.service.UserServiceImpl.register(..))"/>
		<aop:advisor advice-ref="" pointcut-ref="">
</aop:config>
  • 基于标签的事务配置在实战中的应用方式

    <!-- 1. 原始对象-->
    <bean id="userService" class="com.baizhi.service.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>
    <!-- 2. 额外功能-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    **编程的时候 service 负责进行增删改操作的方法 都以modify开头
    						查询操作 命名无所谓  用*号代替
    可以将特殊事务的事务放在前面**
    <tx:advice id="txAdvice" transacation-manager="dataSourceTransactionManager">
    		<tx:attributes>
    				<tx:method name="register" />
    				<tx:method name="modify*"/>
    				<tx:method name="*" propagation="SUPPORTS" read-only="true"/>
    		</tx:attributes>
    </tx:advice>
    
    <!-- 第四步 指定切入点-->
    使用包切入点,应用的过程中 service放置到service包中
    <aop:config>
    		<aop:pointcut id="pc" expression="execution(* com.baizhi.service..*.*(..))"/>
    		<aop:advisor advice-ref="" pointcut-ref="">
    </aop:config>
    

下一章:Spring5学习随笔-基础注解编程文章来源地址https://www.toymoban.com/news/detail-748934.html

到了这里,关于Spring5学习随笔-事务属性详解(@Transactional)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Spring5学习随笔-整合MyBatis(持久层)、连接池、Mapper文件

    Spring5学习随笔-整合MyBatis(持久层)、连接池、Mapper文件

    学习视频:【孙哥说Spring5:从设计模式到基本应用到应用级底层分析,一次深入浅出的Spring全探索。学不会Spring?只因你未遇见孙哥】 JavaEE开发需要持久层进行数据库的访问操作。 JDBC MyBatis、Hibernate进行持久开发过程存在大量的代码冗余 Spring基于模板设计模式对与上述的持

    2024年02月05日
    浏览(32)
  • Spring使用@Transactional 管理事务,Java事务详解。

    B站视频:https://www.bilibili.com/video/BV1eV411u7cg 技术文档:https://d9bp4nr5ye.feishu.cn/wiki/HX50wdHFyiFoLrkfEAAcTBdinvh 简单来说事务就是一组对数据库的操作 要么都成功,要么都失败。 事务要保证可靠性,必须具备四个特性:ACID。 A:原子性:事务是一个原子操作单元,要么完全执行,要么

    2024年02月11日
    浏览(11)
  • Spring5学习随笔-高级注解(@ComponentScan、@Configuration.....),替换XML配置文件

    Spring5学习随笔-高级注解(@ComponentScan、@Configuration.....),替换XML配置文件

    学习视频:【孙哥说Spring5:从设计模式到基本应用到应用级底层分析,一次深入浅出的Spring全探索。学不会Spring?只因你未遇见孙哥】 Spring在3.x提供的新的注解,用于替换XML配置文件。 问题 : 配置Bean在应用的过程中替换了XML具体的什么内容? AnnotationConfigApplicationContext 配

    2024年02月05日
    浏览(9)
  • Spring @Transactional事务传播机制详解

    我们日常工作中极少使用事务传播级别,单纯只是使用事务和rollbackfor抛出异常来解决事务问题,但其实我们很多时候使用的是不正确的,或者说会造成事务粒度过大,本文详解一下事务传播级别,也让自己更好地处理事务问题。 1.什么是事务传播机制? 举个栗子,方法A是一

    2024年02月14日
    浏览(13)
  • Spring5学习随笔-IOC(反转控制)、DI(依赖注入)和创建复杂对象

    Spring5学习随笔-IOC(反转控制)、DI(依赖注入)和创建复杂对象

    学习视频:【孙哥说Spring5:从设计模式到基本应用到应用级底层分析,一次深入浅出的Spring全探索。学不会Spring?只因你未遇见孙哥】 控制:对于成员变量赋值的控制权 反转控制:把对于成员变量赋值的控制权,从代码中反转(转移)到Spring工厂和配置文件中。 好处:解耦合

    2024年02月05日
    浏览(29)
  • Spring5学习随笔-生命周期、自定义类型转换器、后置处理Bean

    Spring5学习随笔-生命周期、自定义类型转换器、后置处理Bean

    学习视频:【孙哥说Spring5:从设计模式到基本应用到应用级底层分析,一次深入浅出的Spring全探索。学不会Spring?只因你未遇见孙哥】 指的是一个对象创建、存活、消亡的一个完整过程 由Spring负责对象的创建、存活、销毁,了解生命周期,有利于我们使用好Spring为我们创建

    2024年02月05日
    浏览(13)
  • Spring 声明式事务 @Transactional(详解)【面试重点,小林出品】

    Spring 声明式事务 @Transactional(详解)【面试重点,小林出品】

            关于 @Transactional 注解的基本使用,推荐看Spring 声明式事务 @Transactional(基本使用)         本篇博客主要学习 @Transactional 注解当中的三个常⻅属性:         1. rollbackFor:异常回滚属性.指定能够触发事务回滚的异常类型.可以指定多个异常类型         2. Iso

    2024年01月25日
    浏览(15)
  • Spring的事务(@Transactional)

    Spring事务的本质,其实就是通过 Spring AOP 切面技术 Spring事务支持2种使用方式 声明式事务(注解方式) 编程式事务(代码方式):代码需要手动控制,比较繁琐,一般不使用 SpringBoot 默认开启了事务 Spring Spring的事务是使用AOP来实现的,在执行目标方法的前和后,加上了事务

    2024年02月21日
    浏览(9)
  • Spring——事务注解@Transactional【建议收藏】

    Spring——事务注解@Transactional【建议收藏】

    在某些业务场景下,如果一个请求中,需要同时写入多张表的数据或者执行多条sql,为了保证操作的原子性(要么同时成功,要么同时失败),避免数据不一致的情况,我们一般都会用到事务;Spring框架下,我们经常会使用@Transactional注解来管理事务; 本篇介绍Spring的事务注

    2024年02月03日
    浏览(14)
  • Spring 事务(编程式事务、声明式事务@Transactional、事务隔离级别、事务传播机制)

    Spring 事务(编程式事务、声明式事务@Transactional、事务隔离级别、事务传播机制)

    本篇重点总结: 在 Spring 项目中使用事务,有两种方式:编程式手动操作和声明式自动提交,声明式自动提交使用最多,只需要在方法上添加注解 @Transactional 设置事务的隔离级别 @Transactional(isolation = Isolation.SERIALIZABLE),Spring 中的事务隔离级别有5种 设置事务的传播机制 @Tra

    2024年02月03日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包