事务的作用
- 数据库个别操作时失败时,提供一种方式使数据库恢复到正常状态,保障数据库即使在异常状态下也能保持数据一致性
- 当出现并发访问数据库时,使多个访问互相隔离,防止访问结果互相干扰
- 事务特征:
- 原子性(Atomic):指事务是不可分割一部分,要么都执行,要么都不执行
- 一致性:事务前后数据的完整性必须保持一致
- 隔离性:并发访问数据库时,为每一个用户开启一个事务,互相隔离
- 持久性:事务一旦提交,对数据库的改变是持久性的,接下来就算数据库发生故障也不会有任何改变
事务隔离级别
- 读未提交
- 会出现脏读的问题
- 读已提交
- 会出现不可重复读取问题
- 可重复度(行级写锁)
- 会出现幻读或者虚读
- 可序列化(表级写锁)
事务管理
概览:
spring是在业务层中控制事务的,它要让所调用的若干个数据层的操作处于同一个事务中,保证他们同时成功或者同时失败
Spring为业务层提供了整套的事务解决方案
- PlatformTransactionManager 接口
- DataSourceTransactionManager 使用于Spring JDBC和MyBatis
- 定义了事务的基本操作
```java //1 获取事务 TransactionStatus getTransaction(TransactionDefinition definition);
//2 提交事务 void commit(TransactionStatus status);
//3 回滚事务 void rollback(TransactionStatus status)
- <br />**此接口定义了事务的基本信息** <br />事务隔离级别的常量参数<br />
<a name="TransactionDefinition"></a>
#### TransactionDefinition
```java
//获取事务的定义名称
String getName();
//获取事务的读写属性
boolean isReadonly();
//获取事务的隔离级别
int getIsolationLevel();
//获取事务的超时时间
//默认是 -1 ,即永不超时
//int TIMEOUT_DEFAULT = -1;
int getTimeout();
//获取事务的传播特征
int getPropagetionBehavior();
- TransactionStatus
- 此接口定义了事务的操作过程中某个时间点上的状态信息及对应的操作状态 ```java //获取事务是否处于新开启事务状态 boolean isNewTransaction();
//获取事务是否处于已完成状态 boolean isCompleted();
//获取事务是否处于回滚状态 boolean isRollbackOnly();
//刷新事务状态 void flush();
//获取事务是否具有回滚存储点 //有的话就回滚到上一个回滚点 boolean hasSavepoint();
//设置事务处于回滚状态 void setRollbackOnly();
<a name="a1c8ebaf"></a>
## 事务的分类
<a name="3bd0ee3e"></a>
#### 编程式事务
```java
public void transfer(String outName, String inName, Double money){
// 步骤1:创建事务管理器
DataSourceTransactionManager dstm = new DataSourceTransactionManager();
// 步骤2:为事务管理器设置与数据层相同的数据源
dstm.setDataSource(dataSource);
// 步骤3:创建事务定义对象
TransactionDefinition td = new DefaultTransactionDefinition();
// 步骤4:创建事务状态对象,用于控制事务执行
TransactionStatus ts = dstm.getTransaction(td);
accountDao.inMoney(outName,money);
// 模拟业务层事务过程中出现错误
int i = 1/0;
30
AOP控制事务
- 把业务层的事务处理功能抽取出来制作AOP通知,利用环绕通知运行期动态织入
声明式事务
- AOP配置事务是否具有特例性?
事务传播行为
概况
- 事务管理员:自己开启的事务是事务管理员
事务协调员:调用的数据库事务时事务协调员
例如:A方法调用了B方法,而且A方法和B方法中都有事务,此时A的事务就是事务管理员,B的事务就是事务协调员
事务传播行为:描述事务协调员针对事务管理员携带事务的处理态度(事务协调员的事务和事务管理员的事务之间的关系)
- 七种事务传播行为(管理员M1.协调员M2)
- 用得比较多的,required和supports
- required:
- M1开启事务T1,M2加入M1开启的事务T1
- M1未开启事务,M2会新建事务T1
- requires_new:带不带事务,都新建一个
- MI开启事务T1,M2创建新的事务T2
- M1未开启事务,M2创建新事务T2
- supports:
- M1开启事务T1,M2加入M1开启的事务T1
- M1未开启事务,M2不加入也不创建
- not_supported:不支持事务
- M1开启事务,M2不开启事务
- M1未开启事务,M2也不开启事务
- Mandatory:必须有事务,没有的话我就报错了
- M1开启事务T1,M2加入M1开启的事务T1
- M1未开启事务,M2报错(error)
- Never:一定不要带事务
- M1开启事务T1,M2报错
- M1未开启事务,M2也不开启事务
- nested:设置savePoint,一旦事务回滚,事务将回滚到savePoint处,交由客户端响应提交/回滚