ssh
Spring配置文件中声明式事务依赖AOP,SpringAOP解决了什么问题
解决依赖注入的问题,方法加强,解耦
Spring的声明式事务管理在底层是建立在AOP的基础之上的,本质是对象方法前后进行拦截,然后在方法执行之前创建或加入一个事务,在执行完目标方法之后根据实际情况进行提交或回滚事务。
最大的优点是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明,便可以将事务规则应用到业务逻辑中。
声明事事务有两种常用的方式
- 基于
和 命名空间的xml配置文件; - 基于@Transactional注解
事务提交与回滚:
提交:
事务里的所有操作都正常完成,将所有对数据的修改写入数据库中。
回滚:
事务中的程序或数据处理出现错误,将程序或数据恢复到上一次正确的行为。
事务传播行为:解决事务嵌套问题
PROPAGATION_REQUIRED
如果存在一个事务,则支持当前事务。如果没有事务则开启一个新事务。
PROPAGATION_SUPPORTS
如果存在一个事务,支持当前事务,事务地执行。如果没有事务,则非事务地执行。
PROPAGATION_MANDATORY
如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
PROPAGATION_REQUIRES_NEW
使用PROPAGATION_REQUIRES_NEW,需要使用JtaTransactionManager作为事务管理器。它会开启一个新的事务。如果一个事务已经存在,则先将这个存在的事务挂起。
PROPAGATION_NOT_SUPPORTED
PROPAGATION_NOT_SUPPORTED总是非事务地执行,并挂起任何存在的事务,如果使用 PROPAGATION_NOT_SUPPORTED,也需要使用JtaTransactionManager作为事务管理器。
PROPAGATION_NEVER
总是非事务地执行,如果存在一个活动事务,则抛出异常。
PROPAGATION_NESTED
如果一个活动地事务存在,则运行在一个嵌套的事务中。如果没有事务,则按照TransactionDefinition.PROPAGATION_REQUIRED 属性执行。
事务隔离机制:
事务的四大特性(ACID):
原子性
操作要么全部成功,要么全部失败
一致性
事务执行前和执行后处于一致性状态。例如,转帐前A、B共5000元,A、B之间转账后,两者之和还应是5000元。
隔离性
事务之间互不干扰
持久性
事务一旦提交,数据的改变是永久的,即使这时候数据库发生故障,数据也不会丢失。
事务之间干扰后产生现象:
脏读
单行数据
读到了别的事务回滚前的脏数据。比如事务B执行过程中修改了数据X,在未提交前,事务A读取了X,而事务B却回滚了,这样事务A就形成了脏读。
不可重复读
单行数据 一个事务在不停提交,另一事务一直不提交。幻影结果。
被其他事务影响,导致本次事务中多次读取同一数据时数据值不一致。比如事务A先读取了一条数据,然后执行逻辑的时候,事务B将数据修改了,然后事务A再次读取时,发现数据不一致。
幻读
多行数据 一个事务在不停提交,另一事务一直不提交。幻影行。
一个事务根据查询条件查询记录总数,得到的记录条数不一致。是不可重复读的一种特殊场景。比如事务A首先根据条件索引得到10条记录,然后事务B修改了数据库中的一条记录,导致也符合事务A的搜索条件,这样事务A再次搜索就发现有11条记录,产生幻读。
事务的隔离级别
读未提交
事务尚未提交,其他事务即可以看到该事务的修改结果。隔离级别最差,脏读,不可重复读,幻读都不能避免。
读已提交
事务只能看到其他事务提交后的数据。可避免脏读,不可避免不可重复读,幻读。
可重复读 默认级别
一个事务多次查询,无论其他事务对数据如何修改,看到的数据都是一致的。因为A事务在查询数据时,若B在修改数据,A事务看到的永远是B事务执行前的数据。只有当A提交或回滚后,看到的才是最新的被B修改过的数据。可避免脏读、不可重复读,无法避免脏读。
序列化
事务顺序执行,可避免脏读、不可重复读、幻读。效率最差,因为A事务执行时,其他事务都得等待。