Spring事务管理
什么是事务管理
在 Spring 框架中事务管理有两种方式:一种是传统的编程式事务管理,即通过编写代 码实现的事务管理;另一种是基于 AOP 技术实现的声明式事务管理。由于在 Spring 框架中, 编程式事务管理很少使用,所以我们只对 Spring 的声明式事务管理进行详细讲解。
Spring 的声明式事务管理在底层采用了 AOP 技术,其最大的优点在于无须通过编程的 方式管理事务,只需要在配置文件中进行相关的规则声明,就可以将事务规则应用到业务逻 辑中。
我们在面试时,面试官有时候会问,在使用spring框架时是否有使用过AOP,这实际上是一个坑,我们在使用了声明式事务管理后,就使用了其底层的AOP技术。
Spring 实现声明式事务管理主要有两种方式:
基于 XML 文件方式的声明式事务管理。
通过 Annotation 注解方式的事务管理。
数据库事务的特性
什么是事务
事务是作为一个逻辑单元执行的一系列操作。一个事务工作单元必须有四个特性:原子 性、一致性、隔离性、持久性。只有这样才能成为一个事务。
事务有什么用
事物对于数据库的作用是对数据的一系列操作,要么全部成功,要么全部失败,防止中 间状态的出现,以确保数据库中的数据始终处于正确的状态。
事务的 ACID 特性
数据库的事务的 ACID 特性由数据库的事务管理系统来保证的。
原子性(Atomicity):事务中的所有操作作为一个整体像原子一样不可分割,要么全部成功, 要么全部失败。
一致性(Consistency):事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执 行之前和执行之后,数据库都必须处于一致性状态。如果数据库系统在运行过程中发生故障,有些事务尚未完成就被迫中断,这些未完成的事务对数据库所作的修改有一部分已写入物理 数据库,这时数据库就处于一种不正确的状态,也就是不一致的状态
隔离性(Isolation):并发执行的事务不会相互影响,其对数据库的影响和它们串行执行时 一样。比如多个用户同时往一个账户转账,最后账户的结果应该和他们按先后次序转账的结 果一样。
持久性(Durability):事务一旦提交,其对数据库的更新就是持久的。任何事务或系统故障 都不会导致数据丢失。
一致性是事务的最终目的,原子性、隔离性、持久性都是为了实现一致性。
事务的隔离性
不考虑事务的隔离性会导致三个问题
脏读、不可重复读、幻读(虚读)
要知道,不可重复读和幻读有区别:
不可重复读发生在事务更新时改变的数据,幻读一般发生在新增改变的数据
解决办法(四种隔离级别)
Read Uncommited(读取未提交内容)会产生脏读
Read Commited(读取提交内容) 解决脏读问题 读提交两次查询会产生不同的查询结果,就会造成不可重复读问题
Repeatable Read(重复读)解决不可重复读问题 可能还会有幻读问题
Serializable(可串行化)解决幻读问题
大多数数据库默认的事务隔离级别是 Read committed,比如 Sql Server , Oracle。
Mysql 的默认隔离级别是 Repeatable read。
隔离级别的设置只对当前链接有效。对于使用 MySQL 命令窗口而言,一个窗口就 相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于 JDBC 操作数据库来说,一个 Connection 对象相当于一个链接,而对于 Connection 对象 设置的隔离级别只对该 Connection 对象有效,与其他链接 Connection 对象无关。
Spring 事务管理器
在 Spring 框架中提供了多种事务管理器来进行事务管理。Spring 的事务管理器是基于 AOP 实现的。在 Spring 的事务管理器中包含了配置事务传播行为、隔离级别、只读和超时属性,这些属性提供了事务应用的方法和描述策略。
在 Java EE 项目开发经常会使用分层模式,Spring 的事务处理位于业务逻辑层,它提供 了针对事务的解决方案。
Spring 事务管理接口
在 Spring 的事务模块(spring-tx-5.2.7.RELEASE.jar)中包括了事务管理的三个核心接口。
PlatformTransactionManager 接口
PlatformTransactionManager 接口是 Spring 提供的事务管理器接口,用于管理事务。 Spring 将事务的配置详细信息封装到 TransactionDefinition 对象中,然后通过事务管理器的 getTransaction() 方法获得事务的状态(TransactionStatus),并对事务进行下一步的操作。
该接口中提供了三个事务操作方法,具体如下:
TransactionStatus getTransaction(TransactionDefinition definition):用于获取事务 状态信息。
void commit(TransactionStatus status):用于提交事务。
void rollback(TransactionStatus status):用于回滚事务。
TransactionDefinition 接口
TransactionDefinition 接口是事务定义(描述)的对象,它提供了事务相关信息获取的 方法,其中包括五个操作,具体如下:
String getName():获取事务对象名称。
int getIsolationLevel():获取事务的隔离级别。
int getPropagationBehavior():获取事务的传播行为。
int getTimeout():获取事务的超时时间。
boolean isReadOnly():获取事务是否只读。
TransactionStatus 接口
TransactionStatus 接口是事务的状态,它描述了某一时间点上事务的状态信息。其中包括六个操作,具体如下:
void flush() 刷新事务
boolean hasSavepoint() 获取是否存在保存点
boolean isCompleted() 获取事务是否完成
boolean isNewTransaction() 获取是否是新事务
boolean isRollbackOnly() 获取是否回滚
void setRollbackOnly() 设置事务回滚
Spring 中包含的事务管理器
事务的传播行为
事务传播行为是指:多个含有事务的方法相互调用时,事务如何在这些方法间传播。
Spring 声明式事务管理
Spring 声明式事务管理实现方式:
基于 XML 文件方式实现声明式事务管理。
通过 Annotation 注解方式实现声明式事务管理。
Jar 包依赖
Spring 核心容器模块
spring-beans-5.2.7.RELEASE.jar
spring-context-5.2.7.RELEASE.jar
spring-core-5.2.7.RELEASE.jar
spring-expression-5.2.7.RELEASE.jar
Spring JDBC 模块
spring-jdbc-5.2.7.RELEASE.jar
Spring 事务模块
spring-tx-5.2.7.RELEASE.jar
Spring AOP 模块
spring-aop-5.2.7.RELEASE.jar
AspectJ 框架
aspectjweaver-1.9.5.jar
Spring 整合 AspectJ 框架模块
spring-aspects-5.2.7.RELEASE.jar
Commons-Loggin 日志
commons-logging-1.2.jar
数据库驱动
mysql-connector-java-5.1.48.jar