Spring配置文件中声明式事务依赖AOP,SpringAOP解决了什么问题

解决依赖注入的问题,方法加强,解耦

Spring的声明式事务管理在底层是建立在AOP的基础之上的,本质是对象方法前后进行拦截,然后在方法执行之前创建或加入一个事务,在执行完目标方法之后根据实际情况进行提交或回滚事务。

最大的优点是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明,便可以将事务规则应用到业务逻辑中。

声明事事务有两种常用的方式

  • 基于命名空间的xml配置文件;
  • 基于@Transactional注解

事务提交与回滚:

  1. 提交:

    事务里的所有操作都正常完成,将所有对数据的修改写入数据库中。

  2. 回滚:

    事务中的程序或数据处理出现错误,将程序或数据恢复到上一次正确的行为。

事务传播行为:解决事务嵌套问题

  1. PROPAGATION_REQUIRED

    如果存在一个事务,则支持当前事务。如果没有事务则开启一个新事务。

  2. PROPAGATION_SUPPORTS

    如果存在一个事务,支持当前事务,事务地执行。如果没有事务,则非事务地执行。

  3. PROPAGATION_MANDATORY

    如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

  4. PROPAGATION_REQUIRES_NEW

    使用PROPAGATION_REQUIRES_NEW,需要使用JtaTransactionManager作为事务管理器。它会开启一个新的事务。如果一个事务已经存在,则先将这个存在的事务挂起。

  5. PROPAGATION_NOT_SUPPORTED

    PROPAGATION_NOT_SUPPORTED总是非事务地执行,并挂起任何存在的事务,如果使用 PROPAGATION_NOT_SUPPORTED,也需要使用JtaTransactionManager作为事务管理器。

  6. PROPAGATION_NEVER

    总是非事务地执行,如果存在一个活动事务,则抛出异常。

  7. PROPAGATION_NESTED

    如果一个活动地事务存在,则运行在一个嵌套的事务中。如果没有事务,则按照TransactionDefinition.PROPAGATION_REQUIRED 属性执行。

事务隔离机制:

  1. 事务的四大特性(ACID):

    • 原子性

      操作要么全部成功,要么全部失败

    • 一致性

      事务执行前和执行后处于一致性状态。例如,转帐前A、B共5000元,A、B之间转账后,两者之和还应是5000元。

    • 隔离性

      事务之间互不干扰

    • 持久性

      事务一旦提交,数据的改变是永久的,即使这时候数据库发生故障,数据也不会丢失。

  2. 事务之间干扰后产生现象:

    • 脏读

      单行数据

      读到了别的事务回滚前的脏数据。比如事务B执行过程中修改了数据X,在未提交前,事务A读取了X,而事务B却回滚了,这样事务A就形成了脏读。

    • 不可重复读

      单行数据 一个事务在不停提交,另一事务一直不提交。幻影结果。

      被其他事务影响,导致本次事务中多次读取同一数据时数据值不一致。比如事务A先读取了一条数据,然后执行逻辑的时候,事务B将数据修改了,然后事务A再次读取时,发现数据不一致。

    • 幻读

      多行数据 一个事务在不停提交,另一事务一直不提交。幻影行。

      一个事务根据查询条件查询记录总数,得到的记录条数不一致。是不可重复读的一种特殊场景。比如事务A首先根据条件索引得到10条记录,然后事务B修改了数据库中的一条记录,导致也符合事务A的搜索条件,这样事务A再次搜索就发现有11条记录,产生幻读。

  3. 事务的隔离级别

    • 读未提交

      事务尚未提交,其他事务即可以看到该事务的修改结果。隔离级别最差,脏读,不可重复读,幻读都不能避免。

    • 读已提交

      事务只能看到其他事务提交后的数据。可避免脏读,不可避免不可重复读,幻读。

    • 可重复读 默认级别

      一个事务多次查询,无论其他事务对数据如何修改,看到的数据都是一致的。因为A事务在查询数据时,若B在修改数据,A事务看到的永远是B事务执行前的数据。只有当A提交或回滚后,看到的才是最新的被B修改过的数据。可避免脏读、不可重复读,无法避免脏读。

    • 序列化

      事务顺序执行,可避免脏读、不可重复读、幻读。效率最差,因为A事务执行时,其他事务都得等待。