Spring AOP 02

连接上文的AOP内容,本文继续记录关于AOP的知识点.

AOP事务处理

事务

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

事务特性:

  • 原子性(Atomicity):一个事务中的多个操作要么都成功要么都失败。
  • 一致性(Consistency): 例如存钱操作,存之前和存之后的总钱数应该是一致的。
  • 隔离性(Isolation):事务与事务应该是相互隔离的。
  • 持久性(Durability):事务一旦提交,数据要持久保存。

spring中事务

spring提供了声明式事务--基于AOP代理,将具体逻辑与事务处理进行解耦.

在SpringBoot项目中,其内部提供了事务的自动配置,当我们在项目中添加了指定依赖spring-boot-starter-jdbc时,框架会自动为我们的项目注入事务管理器对象,最常用的为DataSourceTransactionManager对象.

spring事务实现

spring中最常用的是以@Transactional注解形式进行事务管理.

基于@Transactional 注解进行声明式事务管理的实现步骤分为两步:

  1. 启用声明式事务管理,在项目启动类上添加@EnableTransactionManagement(2.x版本之后也可不添加)
  2. 将@Transactional注解添加到合适的业务类或方法上,并设置合适的属性信息
@Transactional(timeout = 30,
            readOnly = false,
            isolation = Isolation.READ_COMMITTED,
            rollbackFor = Throwable.class)
@Service
public class SysUserServiceImpl implements SysUserService{

注解中属性含义如下:
1)事务属性timeout的含义是:超时时间,是否允许事务超时,默认不允许(-1),一直等

2)事务属性readOnly的含义是:是否为只读事务,(不允许执行更新操作)

3)事务属性rollbackfor的含义是:回滚条件,出现什么异常事务要回滚

norollbackfor: 抛出norollbackfor指定的异常类型,不回滚事务

如果同时写有rollbackFor和norollbackfor表示除了norollbackfor指定的异常不回滚,rollbackfor指定的都回滚

4)事务属性isolation的含义是:用于设置隔离级别(多个事务并发处理可能出现-脏读/不可重复读/幻读)

注意:
@Transactional注解既可以写在类上也可以写在方法上,
当写在类上表示类中所有方法启动事务管理,可以理解为事务的共性体现;
当写在方法上表示此方法要进行事务管理,可以理解为事务的特性体现;
并且方法上的事务比类上的事务优先级要高!

Spring事务管理是基于接口代理(JDK)或动态字节码(CGLIB)技术,然后通过AOP实施事务,系统会通过目标对象的代理对象调用DataSourceTransactionManager对象,在事务开始的时,执行doBegin方法,事务结束时执行doCommit或doRollback方法,这里的方法都是指AOP的通知方法.

事务的传播特性

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

需要注意的是:只有不同业务的不同方法相互调用才是传播特性,同业务内不同方法的调用不是.

常用的传播方式有两种:

1)@Transactional(propagation=Propagation.REQUIRED)
如果没有事务创建新事务, 如果当前有事务参与当前事务(默认)

Spring AOP 02_第1张图片
如官网中给出的图所示,在这个调用链中三个方法会在事务传播机制中工作时处于同一个事务中.

2)@Transactional(propagation=Propagation.REQUIRES_NEW)
必须是新事务, 如果有当前事务, 挂起当前事务并且开启新事务

Spring AOP 02_第2张图片
如官网中给出的图所示,在这个调用链中三个方法会在事务传播机制中工作时都分别始终处于一个新的事务中.

AOP异步操作

应用场景

在开发中通常会考虑系统性能问题-->提升性能一个重要思想就是该串行为并行-->考虑到并行就离不开异步

异步实现

分为两步:

1)在启动类上添加注解@EnableAsync-->spring容器启动时会创建线程池

2)在需要异步执行的业务方法上,使用@Async方法进行异步声明

@Async描述的方法表示要运行在一个独立线程中(这个线程由spring框架内置线程池提供);
@Async描述的方法为一个异步切入点方法(此方法会运行在一个spring框架提供的线程中)

线程池配置

当我们需要自己对spring框架提供的线程连接池进行一些简易配置:

task:
    execution:
      pool:
        core-size: 10 
        #定义核心线程数,当池中线程没有达到这个值时,每来一个任务都会创建一个新的线程
        queue-capacity: 256 
        #任务队列,当来了新的任务,核心线程都在忙,假如队列还没有满,则将任务先扔到队列
        max-size: 256 
        #当核心线程都在忙,任务队列也满了,再来新的任务在创建新的线程,最多可以创建多少个由这个参数决定
        keep-alive: 6000 
        #当并发访问高峰期过后,有些线程可能会空闲下来,超过一定的时间,线程要被释放,这个时间由这个参数决定
      thread-name-prefix: cgb-db-thread- 
      #为池中的线程起个名字前缀

AOPCache操作

应用场景

业务方法中我们可能调用数据层方法获取数据库中数据,假如访问数据的频率比较高,为了提高的查询效率,降低数据库的访问压力,可以在业务层对数据进行缓存

缓存实现

分为两步:
1)在项目(SpringBoot项目)的启动类上添加@EnableCaching注解,以启动缓存配置

2)在需要进行缓存的业务方法上通过@Cacheable注解对方法进行相关描述.表示方法的返回值要存储到Cache中,假如在更新操作时需要将cache中的数据移除,可以在更新方法上使用@CacheEvict注解对方法进行描述

    @Cacheable(value = "menuCache")
    @Override
    public List> findObjects() {}

@Cacheable 注解描述的方法为一个缓存切入点方法,此方法执行之前会从缓存存取数据,缓存没有数据在从数据库操作
value属性的值表示要使用的缓存对象,名字自己指定,其实底层为一个map对象

    @CacheEvict(value = "menuCache",allEntries = true,beforeInvocation = false)
    @Override
    public int deleteObject(Integer id) {

@CacheEvict 注解描述的方法也是一个缓存切入点方法,这个方法会在目标方法执行之前或之后执行缓存清除动作,
1)value属性用于指定缓存对象的名称
2)allEntries用于指定是否清除缓存所有数据
3)beforeInvocation用于指定清除缓存的动作在目标方法执行之前还是之后执行,这里的false表示之后

你可能感兴趣的:(aop)