Spring事务(通俗易懂)

本文主要介绍Spring的实现方式、隔离级别、传播机制以及事务何时失效。

1.事务的实现方式
spring事务的实现方式有两种,编程式事务声明式事务,编程式事务要手动管理事务,实际开发当中基本不会使用。本文主要重点介绍声明式事务,声明式事务管理有三种实现方式:基于TransactionProxyFactoryBean的方式、基于AspectJ的XML方式、基于注解的方式。下面主要介绍常用的两种
基于AspectJ的XML方式
在spring核心配置文件中添加事务管理器的配置、事务的增强以及切面

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

   <!--配置事务的通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="transfer*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

    <!--配置切面-->
    <aop:config>
        <aop:pointcut id="pointcut1" expression="execution(* com.tx.service.impl.*ServiceImpl.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1" />
    </aop:config>

基于注解的方式
在spring核心配置文件中添加事务管理器的配置和开启事务注解

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

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

在事务方法中添加@Transaction注解

@Transactional
public void transferMoney(String source, String destination, Long amount) {

   transferDao.payMoney(source, amount);
   int i = 100/0;
   transferDao.collectMoney(destination, amount);
}

当然,如果是使用springboot,只需要在启动类类上添加@EnableTransactionManagement注解,开启事务支持,在事务方法中添加@Transaction注解就可以使用了。

在一个方法上面添加@Transactional注解之后,spring会基于这个类生成一个代理对象,(如果一个类当中所有的方法都没有加@Transactional注解,那么这个代理对象是不会生成的),
当使用代理对象的方法时,如果方法上存在@Transactional注解,那么代理逻辑会把事务的自动提交设置为fasle,然后再去执行原本的逻辑代码,如果执行逻辑代码没有出现异常,那么代理逻辑中就会将事务进行提交,如果执行业务逻辑方法出现了异常,那么则会将事务进行回滚。
当然,针对哪些异常回滚事务是可以配置的,可以利用@Transaction注解中的rollbackFor属性进行配置,默认情况下会对RuntimeException和Error进行回滚。
总而言之,@Transactional注解方式的事务,使用到了代理模式,代理模式参考

2.事务的隔离级别

Spring事务隔离级别比数据库事务隔离级别多一个default

  1. DEFAULT (默认)
    这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应。

  2. READ_UNCOMMITTED (读未提交)
    这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。

  3. READ_COMMITTED (读已提交)
    保证一个事务修改的数据提交后才能被另外一个事务读取,另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。

  4. REPEATABLE_READ (可重复读)
    这种事务隔离级别可以防止脏读、不可重复读,但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了不可重复读。

  5. SERIALIZABLE(串行化)
    这是花费最高代价但是最可靠的事务隔离级别,事务被处理为顺序执行。除了防止脏读、不可重复读外,还避免了幻像读。

3.事务的传播机制

  1. REQUIRED:默认的传播机制,如果当前不存在事务,则创建一个事务,如果存在事务,则加入事务
  2. SUPPORTS:如果当前不存在事务,则以非事务方式运行,如果存在,则加入
  3. MANDOTOEY:如果当前不存在事务,抛出异常,如果存在,就加入
  4. REQUIRED_NEW:如果当前不存在事务,就创建,如果存在,就挂起
  5. NOT_SUPPORTED:如果当前不存在事务,就以非事务方式运行,如果存在,就挂起当前事务
  6. NEVER:以非事务方式运行,如果当前存在事务,就抛出异常
  7. NESTED:如果当前不存在事务,就创建一个事务,如果当前存在,就在嵌套事务中执行

上面的描述想必大家都知道,那么该怎么理解呢?
举个例子:方法A 调用 方法B
上面所说的当前是描述方法A的,上面那7个属性是修饰方法B的

在这里插入图片描述

上面代码可以看出,方法A不存在事务,即是当前不存在事务,方法B又是默认的传播机制,所以方法A会创建一个事务,在事务当中运行。其它的以此类推。

为什么本类之间的方法调用不用this,而使用当前类对象呢?因为使用this,事务会失效,因为事务底层使用的是代理模式,this是代理模式的真实对象,testService才是代理对象

3.spring事务什么时候会失效?

  1. 同一个类当中的方法使用this调用会失效,因为事务是spring帮我们在底层生成了一个代理对象,如果是this的话,使用的是当前对象,而不是代理对象
  2. 方法不是public,因为事务的设计就是被外部调用的,不是public就不行
  3. 数据库不支持事务,如果数据库都不支持事务,那么spring再牛逼也做不了事务,像如果mysql使用的是myISIM引擎,它就不支持事务,这时候事务也会失效
  4. 异常被吃掉,异常被try{} catch了,事务也是会失效的
  5. 没有被spring管理
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOP(面向切面编程)是 Spring 框架中的一个核心概念,它允许我们在方法执行的前、后或抛出异常时插入额外的逻辑,以实现横切关注点的功能。简单来说,AOP 可以在不修改原始代码的情况下,将额外的功能模块与程序的核心逻辑分离开来,提高了代码的可维护性和可复用性。 在 Spring AOP 的实现过程中,我们需要定义切面类,并为需要实现 AOP 的方法添加注解。Spring 框架会在运行时根据这些注解,自动将切面逻辑插入到方法中,从而实现 AOP 的功能。切面类中的方法,被称为通知(advice),它定义了在方法执行的前、后或抛出异常时需要执行的逻辑。Spring AOP 提供了以下几种通知类型: 1. 前置通知(Before advice):在目标方法执行之前执行的逻辑。 2. 后置通知(After returning advice):在目标方法成功执行后执行的逻辑。 3. 异常通知(After throwing advice):在目标方法抛出异常后执行的逻辑。 4. 最终通知(After advice):在目标方法执行完毕后无论是否抛出异常都执行的逻辑。 5. 环绕通知(Around advice):在目标方法执行的前后都可以执行的逻辑。 通过使用这些通知,我们可以将不同的功能模块以切面的形式插入到目标方法中,实现对方法的增强和控制。这样,我们就可以将一些共性的操作(如日志记录、事务管理等)从核心逻辑中分离出来,提高了代码的可维护性和可复用性。 总结起来,Spring AOP 的原理就是通过在运行时动态生成代理对象,将切面逻辑织入到目标方法中,实现对方法的增强和控制。这种方式可以在不修改原始代码的情况下,实现横切关注点的功能,提高了代码的可维护性和可复用性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Spring 之 AOP 原理详解](https://blog.csdn.net/wizard_hu/article/details/130123613)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Spring AOP概念理解](https://blog.csdn.net/zzpitheilang/article/details/83634727)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值