事务四大特效ACID:
- 原子
- 一致
- 隔离
- 持久
数据不一致
- 丢失修改
T1,T2两个事务同时对一个数据进行修改,T1先修改,T2随后修改,T2的修改覆盖了T1修改,T1修改丢失
- 读脏数据
T1修改数据后写入,T2读取这个修改后的数据,T1回滚撤销了修改,T2读的数据就是假的无效数据
- 不可重复读
T1读入数据,T2对数据进行修改,如果T1再读这个数据,两次读入结果不同
- 幻读
读入数据之间插入了新的数据,某个事务在读取某个范围内的记录时,另一个事务会在范围内插入数据,当之前事务再次读取该记录时,会产生幻行
隔离级别
- 未提交读 read uncommitted
有脏读,可读取其他事务未提交的数据
- 提交读 read committed
只能读取已提交数据,避免脏读,允许不可重复读和幻读 (sqlServer oracle默认)
- 可重复读 repeatable read
有幻读,同一个事务中多次读取同样的记录结果一致, 避免脏读,不可重复读,允许幻读(mysql innoDB默认)
- 可串行化 serialixable
强制事务串行执行,事务只能一个一个执行,避免了脏读、不可重复读、幻读。执行效率慢,使用时慎重
Spring事务
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
方法上添加标签,执行dao层时抛出错误就会回滚,propagation参数为方法调用之间事务的处理方式,rollbackFor为哪些check错误捕获回滚,不添加则只回滚uncheck错误
- required
支持当前事务,如果当前没有事务,就新建事务。默认,
- required_new
新建事务,如果当前存在事务,就把当前事务挂起。新建的事务将和被挂机的事务没有关系,相互独立,外层事务失败回滚,内存事务不回滚,内存事务抛出异常失败回滚,外层事务捕获到异常,也可以不回滚
- supports
支持当前事务,如果当前没有事务就以非事务方式执行
- mandatory 强制
支持当前事务,如果当前没有事务,就抛出异常
- not_supported
以非事务方式执行,如果当前存在事务,就把当前事务挂起
- never
以非事务方式执行,如果当前存在事务,则抛出异常
- nested
如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。(意思就是可以同时满足required特性和required_new特性)