1事务的四大特性
原子性:事务内的动作要么同时成功,要么同时失败。
一致性:一旦事务完成,系统必须保持数据一致。
隔离性:不同事务同时进行时,不会相互影响。
持久性:一旦一个事务完成,这个事务所造成的影响就是持久性的。
2基本事务属性
传播行为 隔离规则 回滚规则 事务超时 是否只读
3传播行为
概念:当事务方法被另一个事务方法调用时,必须指定事务如何传播。
七种事务传播行为
PROPAGATION_REQUIRED:表示当前方法必须运行在事务中。如果当前事务存在,方法将会在该事务中运行。否则,会启动一个新的事物。
PROPAGATION_SUPPORTS:表示当前方法不需要事务上下文,但如果当前存在事务的话,那么该方法会在这个事务中进行。
PROPAGATION_MANDAORY:表示该方法必须在事务中运行,如果当前事务不存在,则抛出异常。
PROPAGATION_REQUIRED_NEW:表示当前方法运行在自己的事务中。如果存在当前事务,则当前事务会被挂起。
PROPAGATION_NOT_SUPPORTS:表示该方法不应该运行在事务中。如果存在当前事务,在该方法运行期间,当前事务将被挂起。
PROPAGATION_NEVER:表示当前方法不应该运行在事务上下文中。如果当前正有一个事务在运行,则会抛出异常。
PROPAGATION_NESTED:表示如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独地提交或回滚。如果当前事务不存在,那么其行为与PROPAGATION_REQUIRED一样。注意各厂商对这种传播行为的支持是有所差异的。可以参考资源管理器的文档来确认它们是否支持嵌套事务。
4隔离级别
读未提交:最低的隔离级别,允许读取尚未提交的数据变更,可能导致脏读,幻读,不可重复读。
读已提交:允许读取并发事务已经提交的数据,可以阻止脏读,但是会有幻读,不可重复读。
可重复读:可以阻止脏读,不可重复读,但会有幻读。
序列化:最高的隔离级别,完全服从acid,通过完全锁定事务相关数据来实现。
5只读
通过事务的只读,可以对数据库进行优化。
6事务超时
事务超时就是对事务定个定时器,在特定时间内事务没有执行完毕,那么就自动回滚,而不是一直等待。
7回滚规则
这些规则定义了事务遇到不同的异常是否回滚,默认情况下,事务只有在运行时异常才会回滚,遇到检查型异常不会回滚。
8编程式事务和声明式事务区别
编成式侵入到业务代码里面,但提供了更加详细的事务管理。声明式事务通过aop,所以可以进行事务管理,但不影响业务代码。
9事务嵌套
案例描述:
controller层方法
service层两个方法
测试一 :默认两个都是@Transactional注解
结果:插入失败,删除失败。(默认事务传播属性REQUIRE,两个方法是一个事务,第二个方法抛异常,所以事务回滚)
测试二:在add方法上将事务传播改成REQUIRES_NEW
结果:插入成功,删除失败。(两个事务相互独立,第二个方法的事务回滚不影响第一个事务)
测试三:在del方法上将事务传播改成REQUIRES_NEW
结果:同测试二。
注意:spring事务时基于aop实现的。(只有来自外部方法的调用才会被代理类捕获,类内部的方法不会被aop代理)
结果:插入失败,删除失败。(del方法是在add方法内部调用,del上的事务无效,则del和add一个事务,del抛出异常,则整个事务回滚)