spring事务

80 阅读3分钟

事务简介

事务:不可分割的原子操作。即一系列的操作要么同时成功,要么同时失败。

开发过程中,事务管理一般在service层,service层中可能会操作多次数据库,这些操作是不可分割的。否则当程序报错时,可能会造成数据异常。

如:张三给李四转账时,需要两次操作数据库:张三存款减少、李 四存款增加。如果这两次数据库操作间出现异常,则会造成数据错误

spring事务管理方案

image.png

  • 编程式事务 (一般不使用)

    通过编写代码实现事务管理

  • 声明式事务 (推荐使用)

    通过AOP技术实现事务管理

在Spring框架中,编程式事务管理很少使用,我们对声明式事务管理进行详细学习。

Spring的声明式事务管理在底层采用了AOP技术,其最大的优点在于无需通过编程的方式管理事务,只需要在配置文件中进行相关的规则声明,就可以将事务规则应用到业务逻辑中。

image.png

事务管理器

image.png spring依赖事务管理器进行事务管理, 事务管理器就是一个通知类, 我们为该通知类设置切点为service所有方法就可以完成事务自动管理,由于不同技术操作数据库,进行事务操作的方法不同,如:JDBC提交事务是 connection.commit() ,MyBatis提交事务是 sqlSession.commit() ,所以Spring提供了多个事务管理器。

一般使用表格中第一个

image.png

  • 引入依赖
<!-- 事务管理 -->
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-tx</artifactId>
   <version>5.3.13</version>
</dependency>
<!-- AspectJ -->
<dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.8.7</version>
</dependency>
事务管理器
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
   <property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 进行事务相关配置 -->
<tx:advice id = "txAdvice">
   <tx:attributes>
       <tx:method name="*"/>
   </tx:attributes>
</tx:advice>
<!-- 配置切面 -->
<aop:config>
   <!-- 配置切点 -->
   <aop:pointcut id="pointcut" expression="execution(*com.itbaizhan.service.*.*(..))"/>
   <!-- 配置通知 -->
   <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor>
</aop:config>

事务控制API

  • PlatformTransactionManager接口

    PlatformTransactionManager是Spring提供的事务管理器接口,所有事务管理器都实现了该接口。

  • TransactionDefinition接口

    TransactionDefinition是事务的定义信息对象

  • TransactionStatus接口

    TransactionStatus是事务的状态接口,它描述了某一时间点上事务的状态信息。

事物的相关配置

<tx:advice>中可以进行事务的相关配置:

<tx:advice id="txAdvice">

   <tx:attributes>

       <tx:method name="*"/>

       <tx:method name="find*" read-only="true"/>

   </tx:attributes>

</tx:advice>

<tx:method> 中的属性:

  • name:指定配置的方法。 * 表示所有方法, find* 表示所有以find开头的方法。
  • read-only:是否是只读事务,只读事务不存在数据的修改,数据库将会为只读事务提供一些优化手段,会对性能有一定提升,建议在查询中开启只读事务。
  • timeout:指定超时时间,在限定的时间内不能完成所有操作就会抛异常。默认永不超时
  • rollback-for:指定某个异常事务回滚,其他异常不回滚。默认所有异常回滚。
  • no-rollback-for:指定某个异常不回滚,其他异常回滚。默认所有异常回滚。
  • propagation:事务的传播行为
  • isolation:事务的隔离级别

事务的传播行为

  • 传播级别 propagation image.png

image.png

  • 隔离级别 isolation

image.png

注解配置声明式事务

  • 注册事务注解驱动
<!-- 注册事务注解驱动 -->

<tx:annotation-driven transaction

manager="transactionManager">

</tx:annotation-driven>

在需要事务支持的类上或方法上加@Transactional

在其注解中设置传播级别 progagation 设置隔离级别 isolation 一般取值都是默认