之前说到Spring的事务管理 一直很懵逼 ,只知道事务管理大概是干嘛的。

  网上的博客都是用 银行转账来解释 事务管理,哈哈哈 那我也用这个吧,这个例子的确是最好的。

  说是两个人相互转账,A转500块钱给B,至于A为啥转钱给B那是她们直接的事情。那么问题来了,比如A转钱给B的时候,突然断电了,A 的钱已经从数据库中扣了,但并没有执行存入到B账户的操作。如果没有事务管理,那这500快就没了  但有了事务管理 那之前的这个从A扣的钱 就会回滚 本次操作 就不成功。所以A就不会扣钱 。至于原理是什么,就见下回分享吧。

  言归正传。

  Spring的事务管理分为两种:

  1:编程式的事务管理

    手动编写代码进行事务管理(很少使用)

  2:声明式的事务管理

    2.1 基于TransactionProxyFactoryBean的方式(很少使用)。

    2.2 基于AspectJ的xml方式(经常使用)

    2.3 基于注解@Transaction的方式(经常使用)

  那么我们就来详细说说 这几种事务管理是怎么实现的。

  一:首先 我们得先聊一聊事务的几个要素

  1:事务的传播行为,Propagation 。其主要的参数值有:

    PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 (比较常用)
    PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。 
    PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。 
    PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。 
    PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 
    PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

  2:事务的隔离级别:isolation   

    Serializable:最严格的级别,事务串行执行,资源消耗最大;
    REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
    READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
    Read Uncommitted:保证了读取过程中不会读取到非法数据。
  3:只读性:read-only   true表示只读 false表示可读可写

  4: 发生哪些异常需要回滚:rollback-for (...Exprofesion)
  5:发生哪些异常不回滚 no-rollback-for
  6:timeout :过期信息

  

  二:我们从比较常用的声明式事务管理开始介绍。

   2.1 基于AspectJ的xml方式(经常使用)

    基于AspectJ的和基于注解的事务管理都是采用AOP协助的事务管理方式。而且是Spring的项目,所以在Spring必要的jar包的基础上来进行的

    所以,首先我们需要进入必要的jar包,这里我们采用的是maven引入相关jar包

    

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.4</version>
</dependency>

  然后 我们在Spring的配置文件中加入如下代码:

  首先是注入Spring的事务管理,因为所以的事务管理都是他来实现的。其中dataSourse是你的c3p0链接池,这里就不多做介绍。

  

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <property name="dataSource" ref="dataSource"/>
</bean>

然后是配置事务的相关属性

<!--基于aspectj的事务声明式事务管理方式-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--
propagation :事务传播行为
isolation :事务隔离级别
read-only :只读
rollback-for :发生哪些异常需要回滚
no-rollback-for :发生哪些异常不回滚
timeout :过期信息
-->
      <!--这个是需要进行事务的管理的那个方法名 这里的name一般是 “sava*” “update*” list*” 表示以sava开始的方法都要进行事务的管理-->
<tx:method name="refnumber" propagation="REQUIRED" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>

然后就是进行AOP的切点和切面配置 这里的切入点是 demo下面的servcie.impl的所以包的所有类中的所以方法

<aop:config proxy-target-class="true">
&lt;!&ndash;配置切入点&ndash;&gt;
<aop:pointcut id="pointCut1" expression="execution(* demo.service.impl.*.*(..))"></aop:pointcut>
&lt;!&ndash;配置切面&ndash;&gt;
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut1"/>
</aop:config>

所以 我们就完成了事务管理的配置

测试如下:

在有异常的时候,第一步虽然执行了 但数据库操作并没有成功。

  2.3 基于注解@Transaction的方式(经常使用)

  这个方式 就更加简单了

  

 <!--事务管理-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/>
</bean>
   <!--开启注解-->
<tx:annotation-driven transaction-manager="transactionManager"/>

  在需要进行事务管理的地方 给一个@Transactional的注解就可以。如图所示:其中的配置文件在()中补充。

  

由于时间原因:后面两种不常用的下回再补充。

Spring事务管理——基础会用篇的更多相关文章

  1. [Spring框架]Spring 事务管理基础入门总结.

    前言:在之前的博客中已经说过了数据库的事务, 不过那里面更多的是说明事务的一些锁机制, 今天来说一下Spring管理事务的一些基础知识. 之前的文章: [数据库事务与锁]详解一: 彻底理解数据库事务一 ...

  2. Spring 事务管理基础知识点

    参考文章 spring事物配置,声明式事务管理和基于@Transactional注解的使用 尚硅谷 佟刚 Spring视频教程PPT Spring支持编程式事务管理和声明式事务管理两种方式 编程式事务 ...

  3. Spring事务管理的demo

    事务是逻辑上的一组操作,这组操作要么全部成功,要么全部失败,最为典型的就是银行转账的案例: A要向B转账,现在A,B各自账户中有1000元,A要给B转200元,那么这个转账就必须保证是一个事务,防止中 ...

  4. Spring事务管理之几种方式实现事务

    1.事务认识 大家所了解的事务Transaction,它是一些列严密操作动作,要么都操作完成,要么都回滚撤销.Spring事务管理基于底层数据库本身的事务处理机制.数据库事务的基础,是掌握Spring ...

  5. Spring事务管理之几种方式实现事务(转)

    一:事务认识 大家所了解的事务Transaction,它是一些列严密操作动作,要么都操作完成,要么都回滚撤销.Spring事务管理基于底层数据库本身的事务处理机制.数据库事务的基础,是掌握Spring ...

  6. 阿里面试挂了,就因为面试官说我Spring 事务管理(器)不熟练?

    前言 事务管理,一个被说烂的也被看烂的话题,还是八股文中的基础股之一.但除了八股文中需要熟读并背诵的那些个传播行为之外,背后的"为什么"和核心原理更为重要. ​ 写这篇文章之前,我 ...

  7. Spring 事务管理高级应用难点剖析--转

    第 1 部分 http://www.ibm.com/search/csass/search/?q=%E4%BA%8B%E5%8A%A1&sn=dw&lang=zh&cc=CN& ...

  8. MyBatis6:MyBatis集成Spring事务管理(下篇)

    前言 前一篇文章<MyBatis5:MyBatis集成Spring事务管理(上篇)>复习了MyBatis的基本使用以及使用Spring管理MyBatis的事务的做法,本文的目的是在这个的基 ...

  9. 【转】Spring事务管理

    原文链接 在 Spring 中,事务是通过 TransactionDefinition 接口来定义的.该接口包含与事务属性有关的方法.具体如清单 1 所示: 清单 1. TransactionDefi ...

随机推荐

  1. Docker+SpringBoot远程发布

    Docker+SpringBoot远程发布 发布成功后启动: docker run -di --name demo1.1 -p 8080:8085 demo:1.0 docker run 命令大全:h ...

  2. Eclipse中安装git后pull远程仓库出现错误解决方法

    该图中位置为false 在配置文件中添加如下语句 -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2

  3. Django学习之八:forms组件【对form舒心了】

    目录 Django forms组件 bound and unbound form instance forms渲染有关 隐藏一个字段,不渲染它 form 校验 form类 ModelForm 利用Mo ...

  4. select设置text的值选中(兼容ios和Android)基于jquery

    前一段时间改了一个bug,是因为select引起的.当时我没有仔细看,只是把bug改完了就完事了,今天来总结一下. 首先说option中我们通常会设置value的属性的,还有就是text值的,请参见下 ...

  5. SAP HUM 事务代码HUMO为整托做Scrap

    SAP HUM 事务代码HUMO为整托做Scrap HUMO事务代码查询结果里,选择某个HU, 回车,过账成功, 2019-04-10 写于苏州市.  

  6. 在VS 2017 下创建 Xamarin NuGet Package

    最近在做一个Xamarin for android的项目,有个需求是一次可以从相册中选择多张图片,但是 android API<19 的版本还不支持一次选择多张图片,在网上找了一下,发现原生的组 ...

  7. 用Gogs在Windows上搭建Git服务

    1.下载并安装Git,如有需求,请重启服务器让Path中的环境变量生效. 2.下载并安装Gogs,请注意,在Windows中部署时,请下载MiniWinService(mws)版本. 3.在Maria ...

  8. Android项目实战(五十三):判断网络连接是否为有线状态(tv项目适配)

    一般对于android手机,我们可以通过sdk提供的方法判断网络情况 /** * 获取当前的网络状态 :没有网络-0:WIFI网络1:4G网络-4:3G网络-3:2G网络-2 * 自定义 * * @p ...

  9. Retrofit2.0 设置 连接超时

    Retrofit2.0 这个网络请求框架使用了很久了,最近一次出现一个小插曲. 有一个接口,返回的数据量因为业务的原因 会返回很大的数据量,此时网络不大好的情况下,会出现请求失败的情况 也就是回调了 ...

  10. Html5 Canvas介绍

    1. 获取绘图上下文 var mycanvas = document.getElementById('mycanvas'); var context = mycanvas.getContext('2d ...