spring事务原理
- spring的事务管理是基于 数据库本身的数据处理机制工作的。
- 事务的思想:复杂的步骤要分步进行。但它们要组成一个整体,要么一起成功,要么一起失败。
- 数据库中的事务就是 多个sql语句一起执行。组成一个事务,要么都执行成功。要么都失败。
数据库的四大隔离级别 ACID
- 原子性
事务中所有操作是不可分割的原子单位。要么操作全部成功,要么全部失败。 - 一致性:
无论事务成功与否,数据库状态与其他业务规则数据保持一致。列如转账的总金额。 - 持久性:
事务成功后,物中所有的数据操作都必须被持久化到数据库中。永久存储。 - 隔离性:
不同事务有自己独立的操作空间。每个事务之间相互不干扰。
数据库锁的概念
- 当多个事务同时要操作一个数据表时,只有持有锁的事务才能操作数据,直到前一个事务完成后,后面的事务才有机会对数据进行操作
spring事务管理
- spring提供了专门用于事务处理的API接口。
- spring在高层,建立了统一的 事务抽象模板接口。 不管是什么数据库都可以使用统一的 事务模板进行事务管理
- TransactionTemplate(事务模板) 和 TransactionCallback(事务回调) 指定 具体的操作 就可以通过编程方式 实现事务管理。
spring事务管理的三个核心接口
- TransactionDefinition 用于描述事务的隔离级别,超时时间,是否为只读事务,事务传播规则等 事务属性。
- PlatformTransactionManager 通过 TransactionDefinition 提供的事务属性,创建管理事务。
- TransactionStatus 描述激活事务的状态。
PlatformTransactionManager
- 是spring提供的 平台事务管理器。用来管理事务,
- 方法:
getTransaction : 返回一个存在的事务,或者新建事务。
commit : 事务提交
rollback : 当commit方法抛出异常时,就会回滚事务 - 接口实现类:
DataSourceTransactionManager : JDBC 的事务管理器
//不同的数据库,只需使用不同的 PlatformTransactionManger实现类即可。
TransactionDefinition
-
事务定义的对象。 定义了事务的规则。并可以获取事务的相关信息。
String getName( ); 获取事务对象名称 int getIsolationLevel( ); 获取事务的隔离级别 int getPropagationBehavior( ); 获取事务的传播行为 int getTimeout( ); 获取事务的超时时间 boolean isReadOnly( ); 获取事务是否只读
TransactionStatus
- TransactionStatus接口是事务的状态。描述某一时间点上事务的状态信息。
- 六个方法:
void flush(); 刷新事务 boolean hasSavepoint(); 获取是否存在保存点 boolean isCompleted(); 获取事务是否完成 boolean isNewTransaction(); 获取是否为新事务,如果返回false,表示当前事务是一个已经存在的事务,或者当前操作未运行在事务环境中。 boolean isRollbackOnly(); 获取事务是否回滚 void setRollbackOnly(); 设置事务回滚,将当前的事务设置为rollback-only。通过该标识通知事务管理器只能将事务回滚,事务管理器将通过显式调用回滚命令或抛出异常的方式回滚事务。
事务传播行为
-
事务的传播行为只 一个事物修饰的方法,被嵌套进另一个方法中。事务如何传播:
//比如这样 public void methodA(){ methodB(); //doSomething } @Transaction(Propagation=XXX) public void methodB(){ //doSomething }
七种事务传播行为
- Propagation = xxx,来指定事务的传播行为。
required : 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择 supports : 支持当前事务,当前没事务。就以非事务方式执行。 mandatory : 使用当前事务,没有就抛异常。 requires_new : 新建事务,如果当前已经存在事务,就把它挂起。 not_supported : 以非事务方式执行,如果存在事务,就把它挂起 never : 以非事务执行,如果当前存在事务,就抛出异常。 nested : 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
数据库的并发问题
- 有三大并发问题:
脏读 : 读取到另一个事务中没有提交的数据
不可重复读 : 同一个事务中,两次查询的数据不一致
幻读 : 一个事物中读取到另一个事务,提交的数据。
四大隔离级别
- SERIALIZABLE(串行化) : 解决所有的并发问题,效率贼差,一般不用
- REPEATABLE READ(可重复读;mysql默认级别) : 解决脏读和不可重复读。存在幻读。
- READ COMMITTED(读已提交数据;oracle默认级别) : 解决脏读。存在不可重复读和幻读。
- READ UNCOMMITTED(读未提交数据) : 不能解决所有的并发问题。性能最好,但没人用。