深入理解spring事务

 更新时间:2021年03月01日 17:07:43   作者:徘徊在深夜中的猫  
这篇文章主要介绍了spring事务深入理解,介绍了事物特性,事物隔离级别,事物的具体使用实例,有感兴趣的同学可以研究下

事务介绍

一个事务要么同时成功,要么同时失败

特性

  • Atomic原子性 事务是由一个或多个活动组成的一个工作单元。原子性确保事务中的所有操作全部发生或全部不发生
  • Consistent一致性 一旦事务完成,系统必须确保它所建模的业务处于一致的状态
  • Isolated隔离性 事务允许多个用户对数据进行操作,每个用户的操作不会与其他用户纠缠在一起
  • Durable持久性 一旦事务完成,事务的结果应该持久化

事务隔离级别

  • DEFAULT 使用底层数据库预设的隔离层级
  • READ_UNCOMMITTED (读未提交的数据) 允许事务读取其他并行的事务还没提交的数据,脏读、不可重复读、幻读问题都存在
  • READ_COMMITTED(读已提交的数据) 只允许事务读取其他并行事务提交的数据,可以避免脏读,但是不可重复读和幻读仍存在
  • REPEATABLE_READ(可重复读) 确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新,可以避免脏读和不可重复读,但幻读仍存在(Mysql默认的事务隔离级别)
  • SERIALIZABLE(串行化) 确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,所有并发问题都可以避免,但是性能低下

传播行为

  • PROPAGATION_REQUIRED 支持当前事务,如果当前没有事务,就新建一个事务
  • PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行
  • PROPAGATION_MANDATORY 支持当前事务,如果当前没有事务,就抛出异常
  • PROPAGATION_REQUIRED_NEW 新建事务,如果当前存在事务,把当前事务挂起
  • PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
  • PROPAGATION_NEVER 以非事务方式执行操作,如果当前存在事务,则抛出异常
  • PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行,如果当前没有事务,则新建事务

只读

事务只进行读取操作

readOnly=true 告诉spring当前事务只会进行读取操作,不会进行修改操作,可以帮助数据库引擎优化

注:如果设置为只读的话,千万不要在事务里修改数据,使用只读操作时,spring不会进行加锁处理,如果修改数据的话,会出现问题

事务超时

事务时间过长,则回滚

回滚规则

rollback-for 指事务对于那些检查型异常应当回滚而不提交(默认spring会对所有的运行时异常回滚)

no-rollback-for 指事务对于那些异常继续执行不回滚

事务的使用

create table user(
 id int primary key AUTO_INCREMENT,
 name varchar(20) not null,
 account double 
 )ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 insert into user (name,account) values('张三',1000);
 insert into user (name,account) values('李四',1000);
<!-- 事务 -->
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-tx</artifactId>
 <version>4.3.29.RELEASE</version>
</dependency>

<!-- 事务管理器以及数据源 -->
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-jdbc</artifactId>
 <version>4.3.29.RELEASE</version>
</dependency>

<!-- mysql驱动 -->
<dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 <version>5.1.48</version>
</dependency>

使用注解

在这里采用的是spring中的数据源

<!-- 数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
 <property name="driverClassName" value="com.mysql.jdbc.Driver" />
 <property name="url" value="jdbc:mysql://localhost:3306/spring?useUnicode=true&amp;characterEncoding=utf-8" />
 <property name="username" value="root" />
 <property name="password" value="123456" />
</bean>

<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource"/>
</bean>

<!-- 启用事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

当然由于是使用的注解,不要忘记组件扫描

<context:component-scan base-package="com.zhanghe.study.spring4.beans.tx"/>

之后就可以在要保证事务的方法上配置@Transactional以及在该注解上配置相应的事务隔离级别(isolation)、事务传播行为(propagation)、对哪些异常执行回滚(rollbackFor)以及不执行回滚(noRollbackFor) 默认对运行时异常回滚

使用XML

<!-- 数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
 <property name="driverClassName" value="com.mysql.jdbc.Driver" />
 <property name="url" value="jdbc:mysql://localhost:3306/spring?useUnicode=true&amp;characterEncoding=utf-8" />
 <property name="username" value="root" />
 <property name="password" value="123456" />
</bean>

<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource"/>
</bean>

<!-- 使用xml配置事务属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
 <tx:attributes>
 <!-- 根据方法名指定特定的事务属性 -->
 <tx:method name="get*" read-only="true"/>
 <tx:method name="find*" read-only="true"/>
 <tx:method name="save*" propagation="REQUIRED"/>
 </tx:attributes>
</tx:advice>

<!-- 使用事务切入点,把事务切入点和事务属性关联起来 -->
<aop:config>
 <aop:pointcut id="pointCut" expression="execution(* com.zhanghe.study.spring4.beans.tx.UserService.*(..))"/>
 <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>

到此这篇关于spring事务深入理解的文章就介绍到这了,更多相关spring事务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java Matcher匹配头尾截取替换字符串的案例

    java Matcher匹配头尾截取替换字符串的案例

    这篇文章主要介绍了java Matcher匹配头尾截取替换字符串的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Java 中的抽象介绍

    Java 中的抽象介绍

    这篇文章主要介绍了Java 中的抽象,数据抽象是一种仅向用户显示基本细节的属性。不向用户显示琐碎或非必需的单元,下面文章Java抽象详细内容,需要的朋友可以参考一下
    2021-12-12
  • Java项目打包发布到maven私仓常见的几种方式

    Java项目打包发布到maven私仓常见的几种方式

    这篇文章主要介绍了项目打包发布到maven私仓常见的几种方式,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-03-03
  • 一文了解Spring中拦截器的原理与使用

    一文了解Spring中拦截器的原理与使用

    在web开发中,拦截器是经常用到的功能。它可以帮我们预先设置数据以及统计方法的执行效率等等。今天就来详细的谈一下spring中的拦截器,需要的可以参考一下
    2022-06-06
  • ArrayList和JSONArray边遍历边删除到底该如何做

    ArrayList和JSONArray边遍历边删除到底该如何做

    这篇文章主要介绍了ArrayList和JSONArray边遍历边删除到底该如何做,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • Java判断上传图片格式的实例代码

    Java判断上传图片格式的实例代码

    这篇文章主要介绍了Java判断上传图片格式的实例代码,在文中给大家提到了Java使用文件头的类型判断上传的文件是否为图片类型,需要的朋友可以参考下
    2019-06-06
  • Java基础之SpringBoot整合knife4j

    Java基础之SpringBoot整合knife4j

    Swagger现在已经成了最流行的接口文档生成与管理工具,但是你是否在用的时候也在吐槽,它是真的不好看,接口测试的json数据没法格式化,测试地址如果更改了还要去改配置,接口测试时增加token验证是真的麻烦…针对Swagger的种种缺点,Knife4j就呼之欲出了.需要的朋友可以参考下
    2021-05-05
  • Mybatis批量插入index out of range错误的解决(较偏的错误)

    Mybatis批量插入index out of range错误的解决(较偏的错误)

    这篇文章主要介绍了Mybatis批量插入index out of range错误的解决(较偏的错误),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • 一篇文章带你入门java网络编程

    一篇文章带你入门java网络编程

    网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。本文介绍了一些网络编程基础的概念,并用Java来实现TCP和UDP的Socket的编程,来让读者更好的了解其原理
    2021-08-08
  • SpringAop实现操作日志记录

    SpringAop实现操作日志记录

    这篇文章主要介绍了SpringAop实现操作日志记录的方法,帮助大家更好的理解和使用SpringAop,感兴趣的朋友可以了解下
    2020-12-12

最新评论