typora-root-url: ./img
事务
- 原子性
- 一致性
- 隔离性
- 持久性
编程式事务:
TransactionFilter{try{//获取链接//设置非自动提交chain.doFilter();//成功之后提交}catch(Exception e){//回滚}finally{//关闭连接释放资源}}
声明式事务:
以前通过复杂的编程来编写一个事务, 替换为只需要告诉Spring哪个方法是事务方法即可; Spring自动进行事务控制, 类似AOP环绕通知
事务管理代码的固定模式作为一种横切关注点, 可以通过AOP方法模块化, 进而借助Spring AOP框架实现声明式事务管理
如何为某个方法添加声明式事务:
- 配置出事务管理器
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="tm"><constructor-arg name="dataSource" ref="dataSource"/></bean>
记得导入AOP模块的jar包
- 开启基于注解的事务控制, 依赖tx名称空间
<tx:annotation-driven transaction-manager="tm"/>
- 给事务方法添加@Transactional注解
isolation: Isolation 事务隔离等级可能造成的并发问题:
- 读未提交: 导致脏读;
例如:事务1 事务2 开启事务 开启事务 读字段1数据 ->结果为100 ① 修改字段1数据为200 ② 读字段1数据 ->结果为200 ③ 回滚 ④ 读字段1数据 ->结果为100 ⑤
在第3步时读取数据后, 数据被回滚不存在了
- 读已提交: 避免了脏读, 无法避免不可重复读;
例如:事务1 事务2 开启事务 开启事务 读字段1数据 ->结果为100 ① 修改字段1数据为200 ② 读字段1数据 ->结果为200 ③ 提交 ④ 读字段1数据 ->结果为200 ⑤
从步骤1, 3可发现事务1读到了不同数据
- 可重复毒(快照读): 避免了脏读, 不可重复读
例如:``` 事务1 事务2 开启事务 开启事务 读字段1数据 ->结果为100 ①
读字段1数据 ->结果为100 ③修改字段1数据为200 ②
读字段1数据 ->结果为100 ⑤ ```提交 ④
可发现事务1在读取的数据都没有变化
mysql数据库的可重复读隔离级别也避免了幻读问题
有事务的业务逻辑, 容器中保存的是这个业务逻辑的代理对象
并发修改同一个数据下的排队
事务1 事务2
修改字段1数据为100
修改字段2数据为200
等待前面的事务提交或回滚
提交
完成修改
提交
事务的传播行为

传播行为可以设置事务方法是不是和之前的大事务共享一个事务(使用同一条连接)
propagation = Propagation.REQUIRED的事务方法的其他属性均会继承自上级事务, 自身属性失效; REQUIRED_NEW的事务方法其属性均生效
REQUIRED: 将之前事务的用的连接(connection)传递给该方法使用
REQUIRED_NEW: 直接新建一条连接给该方法使用
本类事务之间调用的就是同一个事务
