开心一笑

【长得好看就出去走走,让其他人感受下外界的美好。
长得不好看就出去走走,让其他人感受下自己在外界的美好。】

新书购买

戳图购买 >>>

5.1 Spring事务介绍

5.1.1 Spring事务回顾

事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性。事务有四大特性(ACID):原子性(atomicity) 、一致性(consistency)、隔离性(isolation)和持久性(durability)。作为企业级应用程序框架,Spring在不同的事务管理API之上定义了一个抽象层。而应用程序开发人员不必了解底层的事务管理API,就可以使用Spring的事务管理机制。
Spring既支持编程式事务管理(也称编码式事务),也支持声明式的事务管理。编程式事务管理是指将事务管理代码嵌入到业务方法中来控制事务的提交和回滚。在编程式事务中,必须在每个业务操作中包含额外的事务管理代码。声明式事务管理是指将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。大多数情况下声明式事务管理比编程式事务管理更好用。Spring通过Spring AOP框架支持声明式事务管理。
数据访问的技术很多,如:JDBC、JPA、Hibernate、分布式事务等。面对众多的数据访问技术, Spring在不同的事务管理API之上定义了一个抽象层PlatformTransactionManager。而应用程序开发人员不必了解底层的事务管理API,就可以使用Spring的事务管理机制。
Spring并不直接管理事务,而是提供了许多内置事务管理器实现,常用的有:DataSourceTransactionManager、JdoTransactionManager、JpaTransactionManager、以及HibernateTransactionManager等等。

5.1.2 Spring声名式事务

Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分。无论哪种配置方式,一般变化的只是代理机制这部分。DataSource和TransactionManager这两部分只会根据数据访问方式有所变化,比如使用Hibernate进行数据访问时,DataSource实现为SessionFactory,TransactionManager的实现为HibernateTransactionManager。

Spring声明式事务配置提供五种方式,而基于 Annotation 注解方式目前比较流行,所以这里只简单介绍基于注解方式配置Spring声明式事务。我们可以使用@Transactional注解在类或者方法上表明该类或者方法需要事务支持。被注解的类或者方法被调用时,Spring开启一个新的事务,当方法正常运行时,Spring会提交这个事务。具体例子如下:

@Transactionalpublic AyUser updateUser() {//执行数据库操作
}

这里需要注意的是,@Transactional注解来自org.springframework.transaction.annotation。Spring提供了@EnableTransactionManagement注解在配置类上来开启声明式事务的支持。使用@EnableTransactionManagement后,Spring容器会自动扫描注解@Transactional的方法和类。

5.1.3 Spring注解事务行为

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。事务的传播行为可以在@Transactional的属性中指定。Spring定义了7种传播行为,具体如表5-1所示。


表5-1 Spring传播行为

隔离级别定义了一个事务可能受其它并发事务影响的程度。在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务。并发,虽然是必须的,可是会导致许多问题,并发事务所导致的问题可以分为以下三类:
① 脏读(Dirty reads):脏读发生在一个事务读取了另一个事务改写但尚未提交的数据。如果改写在稍后被回滚了,那么第一个事务获取的数据就是无效的。
② 不可重复读(Nonrepeatable read):不可重复读发生在一个事务执行相同的查询两次或两次以上,但是每次都得到不同的数据时。这通常是因为另一个并发事务在两次查询期间更新了数据。
③ 幻读(Phantom read):幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录。
针对这些问题,Spring提供了五种事务的隔离级别,具体如下:


表5-2 Spring隔离级别

@Transactional可以通过propagation属性定义事务行为,属性值分别为:REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER以及NESTED,分别对应表5-1中的内容。可以通过isolation属性定义隔离级别,属性值分别为:DEFAULT、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ以及SERIALIZABLE。
还可以通过timeout属性设置事务过期时间,通过readOnly指定当前事务是否是只读事务,通过rollbackFor(noRollbackFor)指定那个或者那些异常可以引起(或不可以引起)事务回滚。

5.2 Spring Boot事务使用

5.2.1 Spring Boot事务介绍

Spring Boot开启事务很简单,只需要一个注解@Transactional 就可以了,因为在Spring Boot中已经默认对JPA、JDBC、Mybatis开启了事事务,引入它们依赖的时候,事物就默认开启。当然,如果你需要用其它的ORM框架,比如BeatlSQL,就需要自己配置相关的事物管理器。
Spring Boot用于配置事务的类为TransactionAutoConfiguration,此配置类依赖于JtaAutoConfiguration和DataSourceTransactionManagerAutoConfiguration,具体查看源码可知,而DataSourceTransactionManagerAutoConfiguration开启了对声明式事务的支持,所以在Spring Boot中,无须显示开启使用@EnableTransactionManagement。

5.2.2 类级别事务

在第二章中,我们已经在Spring Boot中集成Spring Data JPA,同时开发了AyUserRepository类实现JpaRepository接口,JpaRepository接口是不开启事务的,而SimpleJapRepository默认是开启事务的,所以我们需要手工给AyUserRepository添加事务。AyUserRepository类中的方法是在服务层类AyUserServiceImpl中被使用,而事务一般都是加在服务层,因此我们可以在AyUserServiceImpl类上添加@Transactional注解来开启事务。AyUserServiceImpl类开启事务的代码如下:

/*** 描述:用户服务层实现类* @author 阿毅* @date   2017/10/14*/
@Transactional
@Service
public class AyUserServiceImpl implements AyUserService {@Resource(name = "ayUserRepository")private AyUserRepository ayUserRepository;//省略代码
}

@Transactional注解在类上,意味着此类的所有public方法都是开启事务的。

5.2.3 方法级别事务

@Transactional除了可以注解在类上,还可以注解到方法上面。当注解在类上的时候意味着此类的所有public方法都是开事务的。如果类级别和方法级别同时使用了@Transactional注解,则使用方法级别注解覆盖类级别注解。我们可以给AyUserServiceImpl类中的save()方法添加事务,同时在save完成之后抛NullPointException异常,查看数据是否可以回滚,具体代码如下:

/*** 描述:用户服务层实现类* @author 阿毅* @date   2017/10/14*/
//注解在类上
@Transactional
@Service
public class AyUserServiceImpl implements AyUserService {@Resource(name = "ayUserRepository")private AyUserRepository ayUserRepository;//注解在方法上
@Transactional@Overridepublic AyUser save(AyUser ayUser) {AyUser saveUser =  ayUserRepository.save(ayUser);//出现空指针异常
String error = null;error.split("/");return saveUser;}}

5.2.4 测试

5.2.1节和5.2.2节代码开发完成之后,我们在测试类MySpringBootApplicationTests中添加测试方法,具体代码如下

@Testpublic void testTransaction(){AyUser ayUser = new AyUser();ayUser.setId("3");ayUser.setName("阿华");ayUser.setPassword("123");ayUserService.save(ayUser);}

运行testTransaction()单元测试用例,当代码执行完成后,由于方法save保持数据时候,出现空指针,数据会回滚,数据库查询不到保存的数据。现在我们把AyUserServiceImpl类上的@ Transactional注解和save方法上的@ Transactional注解全部注释掉,再次执行testTransaction()单元测试用例,查询数据库,发现数据库多了一条数据。具体如图5-1所示。


图5-1 数据插入到数据库


读书感悟

来自《傅山的世界》

  • 傅山是兼具晚明和清初艺术风格的书法家。一方面,他是求奇最为激进的艺术家,是那个时代最后一位狂草大师;另一方面,他是碑学思想最早的雄辩鼓吹者。
  • 我们认为傅山的民族意识和明遗民立场也影响了他对书法风格的选择。人品的高下决定着书品的高下,正如傅山在诗中提到的唐代书法家柳公权的名言:“用笔在心,心正则笔正”。

经典故事

有一天,龙虾与寄居蟹在深海中相遇,寄居蟹看见龙虾正把自己的硬壳脱掉,只露出娇嫩的身躯。寄居蟹非常紧张地说:龙虾,你怎可以把唯一保护自己身躯的硬壳也放弃呢?难道你不怕有大鱼一口把你吃掉吗?以你现在的情况来看,连急流也会把你冲到岩石去,到时你不死才怪呢?

龙虾气定神闲地回答:谢谢你的关心,但是你不了解,我们龙虾每次成长,都必须先脱掉旧壳,才能生长出更坚固的外壳,现在面对的危险,只是为了将来发展得更好而作出准备。

寄居蟹细心思量一下,自己整天只找可以避居的地方,而没有想过如何令自己成长得更强壮,整天只活在别人的护荫之下,难怪永远都限制自己的发展。

【每个人都有一定的安全区,你想跨越自己目前的成就,请不要划地自限,勇于接受挑战充实自我,你一定会发展得比想像中更好。】


大神文章


其他

如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎鼓励,点赞、顶、欢迎留下宝贵的意见、多谢支持!

第5章 Spring Boot事务支持相关推荐

  1. Spring Boot 事务支持

    如何使用? Spring Boot 使用事务支持,非常简单,底层依然采用的是Spring本身提供的事务管理. 1.在启动类中添加 @EnableTransactionManagement 注解 2.在 ...

  2. 《Spring Boot极简教程》第8章 Spring Boot集成Groovy,Grails开发

    第8章 Spring Boot集成Groovy,Grails开发 本章介绍Spring Boot集成Groovy,Grails开发.我们将开发一个极简版的pms(项目管理系统). Groovy和Gra ...

  3. 19年8月 字母哥 第一章 spring boot 2.x基础及概念入门 这里全部看完了 热部署没出来 第二章在前面2页 用热点公司网不行

    http://springboot.zimug.com/1233100   文档 http://www.zimug.com/page/5     字母哥个人博客 11111 第一章 spring bo ...

  4. 《深入理解 Spring Cloud 与微服务构建》第十六章 Spring Boot Security 详解

    <深入理解 Spring Cloud 与微服务构建>第十六章 Spring Boot Security 详解 文章目录 <深入理解 Spring Cloud 与微服务构建>第十 ...

  5. Spring Boot事务

    一.事务的四个特性 原子性(Atomicity,或称不可分割性) 一致性(Consistency) 隔离性(Isolation,又称独立性) 持久性(Durability) 二.事务的开启 默认设置下 ...

  6. Spring Boot 2.0 配置图文教程第 2 章 Spring Boot 配置## 书信息 demo.book.name=[Spring Boot 2.x Core Action] demo.b

    本章内容 1.自定义属性快速入门 2.外化配置 3.自动配置 4.自定义创建 Starter 组件 摘录:读书是读完这些文字还要好好用心去想想,写书也一样,做任何事也一样 第 2 章 Spring B ...

  7. SpringBoot学习笔记-2:第二章 Spring Boot 配置

    第二章 Spring Boot 配置 1.YAML 配置 SpringBoot 全局配置文件 application.properties application.yml YAML 以数据为中心,比 ...

  8. Spring Boot国际化支持

    文章目录 添加Maven支持 LocaleResolver LocaleChangeInterceptor 定义Message Sources Controller文件 html文件 运行应用程序 S ...

  9. 19年8月 字母哥 第三章 spring boot 配置原理实战 用热点公司网不行

    第三章 spring boot 配置原理实战 3.1.结合配置加载讲解bean自动装配原理 3.2.详解YAML语法及占位符语法 3.3.获取自定义配置的两种实现方法 3.4.配置文件注入值数据校验 ...

最新文章

  1. 基于OpenCV提取特定区域方法汇总
  2. Delphi的内存管理及内存泄露问题
  3. Google和Baidu常用的搜索技巧--转
  4. 软件测试——JUnit中的参数化测试
  5. kali如何安装netcat_Netcat常用方法汇总
  6. 许可证( License LicenseLicenseLicenseLicenseLicense)服务器配置
  7. python中数据用折线图表示_用python处理文本数据
  8. 我的MVVM框架 v0.1发布
  9. 控制抽象之简化客户代码
  10. [转载]博客园MetaWeblog使用帮助
  11. python多线程控制暂停_python中的多线程编程与暂停、播放音频的结合
  12. 2.7 Inception 网络
  13. GPUImage API 文档之GPUImageFilter类
  14. 外星人电脑为什么那么贵_为什么系统门窗那么贵?
  15. 怎样把百度图片设置成传统翻页 瀑布流与传统翻页的转换
  16. 2018年第九届 蓝桥杯 java B组 部分题解
  17. ant 安装依赖bug1
  18. C语言全局变量和局部变量的范围以及区别
  19. 以太网介绍及硬件设计
  20. 避免360浏览器极速模式自动填充表单

热门文章

  1. 哲学-6张图读懂西方哲学发展史和流派
  2. android 画透明圆圈,在填充的Android画布上绘制一个透明圆圈
  3. 关于echarts绘制的世界地图中英文对应表(Echarts-4.1.0版本)
  4. 前端传对象都后端获取参数的时候多了一对双引号
  5. Ipad冬天无法充电
  6. 校园网中锐捷客户端与VMware的NAT转换冲突问题解决
  7. Python struct.pack(“!dHHHH%ds“%len(self.data),tt,0,self.tap_lenght,self.tap_type,0,_data)里的%ds是什么意思
  8. java 三维旋转立方体_iOS-从三维立方体到理解CATransform3DCGAffineTransformm34
  9. python卡路里计算器_VB高手进,求一个简单计算器的VB代码
  10. 现货k线图基础知识怎么学?