动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

四、Spring 事务 正在学Spring , 整理了相关的学习笔记 , 分享给大家共同进步 , 视频看的动力节点王鹤老师讲的spring框架 , 条理非常清晰 , 够详细

  • 视频观看地址
https://www.bilibili.com/video/BV1nz4y1d7uy
4.1 Spring 的事务管理事务原本是数据库中的概念 , 在 Dao 层 。但一般情况下 , 需要将事务提升 到业务层 , 即Service 层 。这样做是为了能够使用事务的特性来管理具体的业  务 。
在 Spring 中通常可以通过以下两种方式来实现对事务的管理:
(1)使用 Spring的事务注解管理事务
(2)使用 AspectJ 的 AOP 配置管理事务
4.2 Spring 事务管理 APISpring的事务管理 , 主要用到两个事务相关的接口 。
(1)事务管理器接口(重点)事务管理器是 PlatformTransactionManager 接口对象 。其主要用于完成 事务的提交、回滚 , 及获取事务的状态信息 。
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
 A、常用的两个实现类
PlatformTransactionManager 接口有两个常用的实现类:
DataSourceTransactionManager:使用 JDBC 或 MyBatis 进行数据库操作时使用 。
HibernateTransactionManager:使用 Hibernate 进行持久化数据时使用 。
B、Spring 的回滚方式(理解)
Spring事务的默认回滚方式是:  发生运行时异常和 error 时回滚 , 发生受 查(编译)异常时提交 。不过 , 对于受查异常 , 程序员也可以手工设置其回滚方式 。
C、  回顾错误与异常(理解)
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
Throwable 类是 Java 语言中所有错误或异常的超类 。只有当对象是此类 (或其子类之一)的实例时 , 才能通过 Java 虚拟机或者 Java的 throw 语句抛出 。
Error 是程序在运行过程中出现的无法处理的错误 , 比如OutOfMemoryError、ThreadDeath、NoSuchMethodError 等 。当这些错误发生时 , 程序是无法处理(捕获或抛出)的 , JVM 一般会终止线程 。
程序在编译和运行时出现的另一类错误称之为异常 , 它是 JVM 通知程序员 的一种方式 。通过这种方式 , 让程序员知道已经或可能出现错误 , 要求程序员对其进行处理 。
异常分为运行时异常与受查异常 。
运行时异常 , 是 RuntimeException 类或其子类 ,  即只有在运行时才出现 的异常 。如 , NullPointerException、 ArrayIndexOutOfBoundsException、 IllegalArgumentException 等均属于运行时异常 。这些异常由 JVM 抛出 , 在 编译时不要求必须处理(捕获或抛出) 。但 , 只要代码编写足够仔细 , 程序足  够健壮 , 运行时异常是可以避免的 。
受查异常 , 也叫编译时异常 , 即在代码编写时要求必须捕获或抛出的异 常 , 若不处理 , 则无法通过编译 。如SQLException  , ClassNotFoundException ,  IOException 等都属于受查异常 。
RuntimeException 及其子类以外的异常 , 均属于受查异常 。当然 , 用户   自定义的 Exception的子类 , 即用户自定义的异常也属受查异常 。程序员在定 义异常时 , 只要未明确声明定义的为 RuntimeException的子类 , 那么定义的 就是受查异常 。
(2)事务定义接口事务定义接口 TransactionDefinition 中定义了事务描述相关的三类常量: 事务隔离级别、事务传播行为、事务默认超时时限 , 及对它们的操作 。
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
A、定义了五个事务隔离级别常量(掌握)
这些常量均是以 ISOLATION_开头 。即形如 ISOLATION_XXX 。
  • DEFAULT : 采 用 DB 默认的事务隔离级别  。 MySql的默认为REPEATABLE_READ;Oracle 默认为 READ_COMMITTED 。
READ_UNCOMMITTED:  读未提交 。未解决任何并发问题 。
READ_COMMITTED:  读已提交 。解决脏读 , 存在不可重复读与幻读 。
REPEATABLE_READ:  可重复读 。解决脏读、不可重复读 , 存在幻读
SERIALIZABLE:  串行化 。不存在并发问题 。
B、定义了七个事务传播行为常量(掌握)
所谓事务传播行为是指 , 处于不同事务中的方法在相互调用时 , 执行期间事务的维护情况 。如 ,   A 事务中的方法 doSome()调用 B 事务中的方法doOther() , 在调用执行期间事务的维护情况 , 就称为事务传播行为 。事务传 播行为是加在方法上的 。
事务传播行为常量都是以 PROPAGATION_ 开头 , 形如PROPAGATION_XXX 。
PROPAGATION_REQUIRED
PROPAGATION_REQUIRES_NEW
PROPAGATION_SUPPORTS
PROPAGATION_MANDATORY
PROPAGATION_NESTED
PROPAGATION_NEVER
PROPAGATION_NOT_SUPPORTED
a、PROPAGATION_REQUIRED:
指定的方法必须在事务内执行 。若当前存在事务 , 就加入到当前事务中; 若当前没有事务 , 则创建一个新事务 。这种传播行为是最常见的选择 , 也是
Spring 默认的事务传播行为 。
如该传播行为加在 doOther()方法上 。若 doSome()方法在调用 doOther() 方法时就是在事务内运行的 , 则 doOther()方法的执行也加入到该事务内执行 。若 doSome()方法在调用 doOther()方法时没有在事务内执行 , 则doOther()方法会创建一个事务 , 并在其中执行 。
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
b、PROPAGATION_SUPPORTS
指定的方法支持当前事务 , 但若当前没有事务 , 也可以以非事务方式执行 。  
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
c、PROPAGATION_REQUIRES_NEW
总是新建一个事务 , 若当前存在事务 , 就将当前事务挂起 , 直到新事务执行完毕 。
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
C、  定义了默认事务超时时限
常量 TIMEOUT_DEFAULT 定义了事务底层默认的超时时限 ,   sql 语句的执 行时长 。
注意 , 事务的超时时限起作用的条件比较多 , 且超时的时间计算点较复 杂 。所以 , 该值一般就使用默认值即可 。
4.3   程序举例环境搭建举例:购买商品 trans_sale 项目
本例要实现购买商品 , 模拟用户下订单 , 向订单表添加销售记录 , 从商品表减 少库存 。
实现步骤:
Step0:创建数据库表创建两个数据库表 sale , goods
sale 销售表
 
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
goods 商品表
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图

goods 表数据
 
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
Step1:   maven 依赖 pom.xml<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.5.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.2.5.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.5.RELEASE</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.1</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId> <version>5.1.9</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.12</version></dependency>插件<build><resources><resource><directory>src/main/java</directory><!--所在的目录 - -><includes><!--包括目录下的.properties,.xml 文件都会扫描到--><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource></resources><plugins><plugin><artifactId>maven-compiler-plugin</artifactId> <version>3.1</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build>
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
Step2:创建实体类创建实体类 Sale 与 Goods
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
Step3:定义 dao 接口定义两个 dao 的接口 SaleDao , GoodsDao
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
 
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
Step4:定义 dao 接口对应的sql映射文件SaleDao.xml
 
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
GoodsDao.xml
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
Step5:定义异常类定义 service 层可能会抛出的异常类 NotEnoughException
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
Step6:定义 Service 接口定义 Service 接口 BuyGoodsService
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
Step7:定义 service 的实现类定义 service 层接口的实现类 BuyGoodsServiceImpl
1)  类定义
 
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
2)  Dao 属性
 
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
3)  Buy 方法
 
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
Step8:修改 Spring 配置文件内容
  • 声明 Mybatis 对象

动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
声明业务层对象
 
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
Step9:定义测试类定义测试类 MyTest 。现在就可以在无事务代理的情况下运行了 。
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
4.4   使用 Spring 的事务注解管理事务(掌握)通过@Transactional 注解方式 ,   可将事务织入到相应 public 方法中 , 实 现事务管理 。
@Transactional 的所有可选属性如下所示:
propagation:  用于设置事务传播属性 。该属性类型为 Propagation 枚举 , 默认值为 Propagation.REQUIRED 。
isolation:  用于设置事务的隔离级别 。该属性类型为 Isolation 枚举 , 默认值为 Isolation.DEFAULT 。
readOnly:  用于设置该方法对数据库的操作是否是只读的 。该属性为boolean , 默认值为 false 。
timeout:用于设置本操作与数据库连接的超时时限 。单位为秒 , 类型为 int , 默认值为-1 , 即没有时限 。
rollbackFor:  指定需要回滚的异常类 。类型为 Class[] , 默认值为空数组 。当然 , 若只有一个异常类时 , 可以不使用数组 。
rollbackForClassName: 指定需要回滚的异常类类名 。类型为 String[] , 默认值为空数组 。当然 , 若只有一个异常类时 , 可以不使用数组 。
noRollbackFor: 指定不需要回滚的异常类 。类型为 Class[] ,  默认值为空数组 。当然 , 若只有一个异常类时 , 可以不使用数组 。
noRollbackForClassName:指定不需要回滚的异常类类名 。类型为 String[] , 默认值为空数组 。当然 , 若只有一个异常类时 , 可以不使用数组 。
【动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务】需要注意的是 ,   @Transactional 若用在方法上 , 只能用于 public 方法上 。对于其他非 public 方法 , 如果加上了注解@Transactional , 虽然 Spring不会报错 , 但不会将指定事务织入到该方法中 。因为 Spring 会忽略掉所有非public 方法上的@Transaction 注解 。
若@Transaction 注解在类上 , 则表示该类上所有的方法均将在执行时织入 事务 。
实现注解的事务步骤:
复制 trans_sale 项目 , 新项目 trans_sale_annotation
1.  声明事务管理器
 
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
2.  开启注解驱动
 
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
transaction-manager:事务管理器 bean 的 id 
3.  业务层 public 方法加入事务属性
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
4.5   使用AspectJ 的 AOP 配置管理事务(掌握)使用 XML 配置事务代理的方式的不足是 , 每个目标类都需要配置事务代 理 。当目标类较多 , 配置文件会变得非常臃肿 。
使用 XML 配置顾问方式可以自动为每个符合切入点表达式的类生成事务代 理 。其用法很简单 , 只需将前面代码中关于事务代理的配置删除 , 再替换为如  下内容即可 。
Step1:复制项目复制 trans_sale 项目 , 并重命名为 trans_sal_aspectj 。在此基础上修改 。
Step2:  maven 依赖 pom.xml新加入 aspectj 的依赖坐标
<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.2.5.RELEASE</version></dependency>
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
Step3:在容器中添加事务管理器
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
Step4:配置事务通知为事务通知设置相关属性 。用于指定要将事务以什么方式织入给哪些方法 。
例如 , 应用到 buy 方法上的事务要求是必须的 , 且当 buy 方法发生异常后要回滚业务 。
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
Step5:配置增强器指定将配置好的事务通知 , 织入给谁 。
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?
Step6:修改测试类测试类中要从容器中获取的是目标对象 。
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
动力节点spring笔记 四 动力节点Spring框架学习笔记-王鹤Spring事务

文章插图
?


?