zoukankan      html  css  js  c++  java
  • 58-Spring-AOP事务管理

    Spring AOP事务处理

    Spring 中事务简介

    事务定义

    ​ 事务(Transaction)是一个业务,是一个不可分割的逻辑工作单元,基于事务可以更好的保证业务的正确性。

    事务特性

    事务具备ACID特性,分别是:

    • 原子性(Atomicity):一个事务中的多个操作要么都成功要么都失败。

    • 一致性(Consistency): 例如存钱操作,存之前和存之后的总钱数应该是一致的。

    • 隔离性(Isolation):事务与事务应该是相互隔离的。

    • 持久性(Durability):事务一旦提交,数据要持久保存。

      ​ 在实际开发中,为了做一定的优化,在一致性方面,可以只保持最终的一致就可以了,这样的事务通常我们会称之为柔性事务

    Spring 中事务管理

    Spring 中事务方式概述

    ​ Spring框架中提供了一种声明式事务的处理方式,此方式基于AOP代理,可以将具体业务逻辑与事务处理进行解耦。也就是让我们的业务代码逻辑不受污染或少量污染,就可以实现事务控制。
    ​ 在SpringBoot项目中,其内部提供了事务的自动配置,当我们在项目中添加了指定依赖spring-boot-starter-jdbc时,框架会自动为我们的项目注入事务管理器对象,最常用的为DataSourceTransactionManager对象。

    Spring 中事务管理实现

    在spring中,进行事务的控制与管理主要通过@Transactional注解进行声明式事务管理

    实现步骤:

    第一步:启用声明式事务管理,在项目启动类上添加@EnableTransactionManagement,新版本中也可不添加

    第二步:将@Transactional注解添加到合适的业务类或方法上,并设置合适的属性信息。

    /**
     * 如果在类的上面使用了事务的注解,而方法上面没有使用事务的注解
     * 那么方法上的事务默认会使用类上面注解事务的属性,也就是共性
     * 但是一旦方法上使用了事务的注解,那么在该方法上的事务的注解的属性就
     * 不会再使用类上面的注解的属性.而是使用其特性,也就是说一旦有特性,共性就会失效
     * 如果特性没有明确,那么就是默认的	
     */ 
    @Transactional(timeout = 30,
                   readOnly = false,
                   isolation = Isolation.READ_COMMITTED,
                   rollbackFor = Throwable.class,
                   propagation = Propagation.REQUIRED)
      @Service 
      public class implements SysUserService {
        @Transactional(readOnly = true)
        @Override
    	 public PageObject<SysUserDept> findPageObjects(
    			String username, Integer pageCurrent) {
             //......
           }
    }
    
    

    注意:

    • @Transactional注解应用在类上时表示类中所有方法启动事务管理,并且一般用于事务共性的定义。当
    • @Transactional描述方法时表示此方法要进行事务管理,假如类和方法上都有@Transactional注解,则方法上的注解一般用于事务特性的定义。

    @Transactional 常用属性应用说明:

    • timeout:事务的超时时间,默认值为-1,表示没有超时显示。如果配置了具体时间,则超过该时间限制但事务还没有完成,则自动回滚事务。这个时间的记录方式是在事务开启以后到sql语句执行之前。
    • read-only:指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
    • rollback-for:用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。
    • no-rollback- for 抛出 no-rollback-for 指定的异常类型,不回滚事务。
    • isolation事务的隔离级别,默认值采用 DEFAULT。

    Spring 中事务传播特性

    事务传播(Propagation)特性指"不同业务(service)对象"中的事务方法之间相互调用时,事务的传播方式常用的有两种:

    @Transactional(propagation=Propagation.REQUIRED) 。

    @Transactional(propagation=Propagation.REQUIRES_NEW)。

    如何理解不同业务对象呢?

    举个简单的例子

    当我们在加载一个用户列表页面的时候,执行的是一个用户业务,但是同时我们需要将用户的操作写入日志,这样的话我们就在一个用户的操作用又应用了一个日志的业务操作,这就是属于不同的业务对象.

    @Transactional(propagation=Propagation.REQUIRED) 。该事务传播方式,是spring中默认的事务传播方式它适合于绝大多数的情况。假设 ServiveX#methodX() 都工作在事务环境下(即都被 Spring 事务增强了),假设程序中存在如下的调用链:Service1#method1()->Service2#method2()->Service3#method3(),那么这 3 个服务类的 3 个方法通过 Spring 的事务传播机制都工作在同一个事务中。

    1595426050101

    示例代码:

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveObject(SysLog sysLog) {
        sysLogDao.insertObject(sysLog);
    
    }
    //使用以上的事务传播的方式时,那么该方法始终工作在一个已经存在的事务方法中
    //或者是由调用者创建的一个事务方法中.那么如果使用了自定义的注解以后,并且没有对
    //自定义的注解设置优先级的话,那么这个注解的优先级就是比较低的,此时事务如果设置了只读操作
    //那么再调用的方法中的事务存在了写操作的话,就会出现异常,一种解决方案就是我们可以对自定义
    //的注解进行优先级设置,让其优先于事务的注解.或者采用事务传播特性的另一个特性:Propagation.REQUIRES_NEW,使用这个特性也可以解决
    

    @Transactional(propagation=Propagation.REQUIRES_NEW)。必须是新事务, 如果有当前事务, 挂起当前事务并且开启新事务,也就是说使用这个注解后,不管外面有多少的限制,在执行这个业务的时候会单独开启一个新的事务,保证数据的一致性操作.

    1595426893672

    示例代码:

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void saveObject(SysLog sysLog) {
        sysLogDao.insertObject(sysLog);
    }
    //当有一个业务对象调用如上业务方法时,此方法会始终运行在一个新的事务中。
    

    例如以下方法调用这个方法,但是以下的方法进行了事务的只读操作控制,但是还可以保证上述方法的写操作完整执行.

    @Transactional(readOnly = true)
    @RequiredLog("用户查询")//该注解可以通过aop进行横切,调用saveObject方法.
    @Override
    public PageObject<SysUserDept> findPageObjects(String username, Integer pageCurrent, Integer pageSize) {
        //参数校验
        if (pageCurrent==null||pageCurrent<1) {
            throw new IllegalArgumentException("页码值不正确");
        }
    }
    

    Spring 中事务管理小结

    ​ Spring 声明式事务是 Spring 最核心,最常用的功能。由于 Spring 通过 IOC 和 AOP的功能非常透明地实现了声明式事务的功能,对于一般的开发者基本上无须了解 Spring声明式事务的内部细节,仅需要懂得如何配置就可以了。

  • 相关阅读:
    Spring(二) Spring装配Bean的几种方式
    Spring(一) Spring配置文件中classpath和classpath*的区别
    学习响应式编程 Reactor (5)
    学习响应式编程 Reactor (4)
    学习响应式编程 Reactor (3)
    学习响应式编程 Reactor (2)
    学习响应式编程 Reactor (1)
    学习Java 8 Stream Api (5)
    学习Java 8 Stream Api (4)
    Spring WebFlux 学习笔记
  • 原文地址:https://www.cnblogs.com/liqbk/p/13363491.html
Copyright © 2011-2022 走看看