认识事务
可以把一系列(多条sql语句)要执行的操作称为事务,而事务管理就是管理这些操作要么完全执行,要么完全不执行(很经典的一个例子是:A要给B转钱,首先A的钱减少了,但是突然的数据库断电了,导致无法给B加钱,然后由于丢失数据,B不承认收到A的钱;在这里事务就是确保加钱和减钱两个都完全执行或完全不执行,如果加钱失败,那么不会发生减钱)。
事务管理的意义:
保证数据操作的完整性和安全性。
事务管理的四大特性: - 记住 - ACID
原子性:事务的整个操作是一个整体,不可以分割,要么全部成功,要么全部失败。
一致性:事务操作的前后,数据表中的数据没有变化。
隔离性:事务操作是相互隔离不受影响的。
持久性:数据一旦提交,不可改变,永久的改变数据表数据。
事务管理操作:
开启事务管理:开启之后,下面的sql语句并不会马上执行并把结果写到表中,而是会写到事务日志中。
start transaction;
回滚操作:会清掉开始事务管理之后写到事务日志中的内容,即恢复到开启事务管理之前。
语法:rollback; - 如果程序发生了异常,将数据恢复到没有操作之前的那个状态。
注意:回滚操作只是回退"写"的内容,对于普通的读表select语句不能回退。
事务提交:将sql语句的结果写到数据表中。
语法:commit: - 持久化的保存
当 commit 或 rollback 语句执行后,事务会自动关闭
Spring事务管理机制
Spring事务管理 由三个接口共同完成 :
lPlatformTransactionManager 平台相关事务管理器 - 事务管理器
lTransactionDefinition 事务定义信息 (通过配置如何进行事务管理:隔离、传播、超时、只读)
lTransactionStatus 事务状态 (事务管理过程中,每个时间点事务 状态信息 )
PlatformTransactionManager 事务管理器

lDataSourceTransactionManager 针对 JdbcTemplate、MyBatis 事务控制 ,使用Connection进行事务控制
开启事务 conn.setAutoCommit(false);
提交事务 conn.commit();
回滚事务 conn.rollback();
lHibernateTransactionManager 针对Hibernate框架进行事务管理, 使用Session的Transaction相关操作进行事务控制
开启事务 session.beginTransaction();
提交事务 session.getTransaction().commit();
回滚事务 session.getTransaction().rollback();
用户应该选择和使用持久层技术,对应的事务管理器
TransactionDefinition 事务定义信息

事务四大特性 ACID --- 隔离性引发问题 ---- 解决事务的隔离问题--隔离级别
Mysql 默认隔离级别 REPEATABLE_READ
Oracle 默认隔离级别 READ_COMMITTED
事务的传播行为
什么是事务的传播行为? 为什么需要 ?
事务传播行为用于解决两个被事务管理的方法互相调用问题

REQUIRED、SUPPORTS、MANDATORY : 支持当前事务, A调用B,如果A事务存在,A和B处于同一个事务 (事务默认传播行为 REQUIRED )
REQUIRES_NEW、NOT_SUPPORTED、NEVER : 不会支持原来的事务 ,A调用B, 如果A事务存在, B肯定不会和A处于同一个事务
NESTED: 嵌套事务 ,只对DataSourceTransactionManager有效 ,底层使用JDBC的SavePoint机制,允许在同一个事务设置 保存点,回滚保存点
面试题:REQUIRED、REQUIRES_NEW、NESTED 区分
REQUIRED 一个事务
REQUIRES_NEW 两个事务
NESTED 一个事务,事务可以设置保存点,回滚到保存点 ,选择提交或者回滚
TransactionStatus 事务状态
事务运行过程中,每个时间点 事务状态信息 !
事务的结束必须通过commit , rollback 作用标记为回滚
try {
操作
commit
} catch (){
rollback
}
三个对象之间的关系:
用户管理事务,需要先配置事务管理方案TransactionDefinition、 管理事务通过TransactionManager 完成,TransactionManager根据 TransactionDefinition进行事务管理,在事务运行过程中,每个时间点都可以通过获取TransactionStatus 了解事务运行状态!
Spring事务管理两种方式
Spring支持两种事务管理: 编程式事务管理、 声明式事务管理 - 支持
l编程式事务管理: 要修改原来的代码,加入事务管理代码 (侵入性 )--- 不推荐,不使用
实际中是通过TransactionTemplate 操作事务管理
template.execute(new TransactionCallbackWithoutResult(){
void doInTransactionWithoutResult(TransactionStatus status) {
// 需要事务管理的代码
}
});
l声明式事务管理: 底层就是AOP的环绕通知, --- 推荐
声明式事务管理案例
编写转账案例,引出事务管理问题
第一步:建立数据表
第二步: 编写转账代码
第三步: 编写测试
XML配置方式添加事务管理(tx、aop约束)
第一步: 引入aop和tx 的名称空间,导入aop和tx 的jar
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
第二步: 配置 transactionManager(spring提供 Around 通知 )
根据不同的持久层框架,配置不同的事务管理器,事务管理器需要依赖数据源信息
第三步: 配置切入点和切面
在spring的配置文件中,使用
使用aop:config来配置切入点和切面信息
aop:pointcut 配置切入点, id=""起个名字,expression="" 配置切入点表达式
aop:advisor 配置切面,advice-ref="" pointcut-ref="" 将切入点和通知整合到一起
注解配合方式添加事务管理@Transactional
第一步: 配置注解驱动事务管理
第二步: 在需要管理事务的方法或者类上面 添加@Transactional 注解
小结
问题: XML配置方式和注解配置方式 进行事务管理 哪种用的多?
XML方式 和注解都在使用
使用@Transactional注解进行事务管理,方便,不过配置太分散, 使用XML进行事务管理 属性集中配置,便于管理和维护 