Spring里面的AOP和事务

1. 什么是spring里面的AOP和AOP的作用?

Spring里面的AOP,就是面向切面编程,及刨开封装对象的内部,把影响多个类的公共方法封装成一个可用的模块,这就是Aspect(切面),这个切面与业务无关,但是被业务模块所调用的方法,减少代码的重复利用,减低代码之间的耦合度,利于后期的维护,主要应用在权限拦截,日志的打印。

2. 什么是事务?为什么需要事务

事务是一系列指令的结合,事务必须要满足ACID,及也就是原子性,一致性,隔离性,持久性。我们在对数据进行读取和修改时,

在同一时刻,不同的业务逻辑对表里面数据进行修改,这样可能引来冲突,这是就需要引入事务,来保证数据的正确性。

3. Spring里面如何支持事务?

两种方式:编程式事务和声明式事务

编程式事务:就是在业务逻辑里面实现事务,可以使用在Spring里面使用TransactionTemplate。

声明式事务:在业务逻辑的方法使用注解,在Spring可以使用配置或者使用注解。

编程式事务和声明式事务优缺点?

编程式事务实现在业务逻辑里面,这样会使业务逻辑比较复杂,增加了代码的耦合性,声明式事务主要应用在方法是使用注解,比较清晰,但是声明式不能用在代码块上,这是它的最大的缺点,如果使用try{}catch处理异常的话,事务将会失去作用。

4.事物场景的应用?

      4.1   第一类丢失更新:小明有200元存款在银行,但是这时候小明的准备卖一本java书,他女朋友看到一个口红,也在这时候准备去卖,小明成功卖到java书,她的女朋友操作失败,进行了事务的回滚,银行卡里面还是200元,此时银行损失100元。

      4.2   脏读:就是一个事务读到另一个未提交的事务。甲取款100元未提交,乙进行转帐查到帐户内剩有100元,这是甲放弃操作回滚,乙正常操作提交,帐户内最终为0元,乙读取了甲的脏数据,客户损失100元。

    4.3 不可重复读:就是两次读取到数据不一致。甲乙同时开始都查到帐户内为200元,甲先开始取款100元提交,这时乙在准备最后更新的时候又进行了一次查询,发现结果是100元,这时乙就会很困惑,不知道该将帐户改为100还是0。

    4.4 虚读:是针对于插入操作过程中的读取问题,如丙存款100元未提交,这时银行做报表进行统计查询帐户为200元,然后丙提交了,这时银行再统计发现帐户为300元了,无法判断到底以哪个为准?

    4.5  第二类丢失更新:是不可重复读的一种特例,如上,乙不做第二次查询而是直接操作完成,帐户内最终为100元,甲的操作被覆盖掉了,银行损失100元。感觉和第一类丢失更新类似。

5.spring事务的回滚注意事项?

       5.1  在spring里面如果在service对业务逻辑使用try{}catch,那么事务将不会进行回滚。

       5.2  如果Service层会抛出不属于运行时异常也要能回滚,那么可以将Spring默认的回滚时的异常修改为Exception,这样就可以保证碰到什么异常都可以回滚。具体的设置方式也说下:

      ransactional(rollbackFor=Exception.class)

6.transaction注解的理解?

7. spring事务的隔离级别?

      ISOLATION_DEFAULT:用底层数据库的默认隔离级别,数据库管理员设置什么就是什么
      ISOLATION_READ_UNCOMMITTED(未提交读):最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏                                   读、不可重复读)
      ISOLATION_READ_COMMITTED(提交读):一个事务提交后才能被其他事务读取到(该隔离级别禁止其他事务读取到未                                   提交事务的数据、所以还是会造成幻读、不可重复读)、sql server默认级别
     ISOLATION_REPEATABLE_READ(可重复读):可重复读,保证多次读取同一个数据时,其值都和事务开始时候的内容是                       一致,禁止读取到别的事务未提交的数据(该隔离基本可防止脏读,不可重复读(重点在修改),但会出现幻读                         (重点在增加与删除))(MySql默认级别,更改可通过set transaction isolation level 级别)
      ISOLATION_SERIALIZABLE(序列化):代价最高最可靠的隔离级别(该隔离级别能防止脏读、不可重复读、幻读)

      数据库隔离级别越高,执行代价越高,并发执行能力越差,因此在实际项目开发使用时要综合考虑,为了考虑并发性能一般         使用提交读隔离级别,它能避免丢失更新和脏读,尽管不可重复读和幻读不能避免,但可以在可能出现的场合使用悲观锁或         乐观锁来解决这些问题。

      悲观锁和乐观锁在后续进行讨论

  8. spring的传播特性?

   1.  PROPAGATION_REQUIRED:支持当前事务,如当前没有事务,则新建一个。(spring里面如何发现当前没有事务,正在研究)
   2.PROPAGATION_SUPPORTS:支持当前事务,如当前没有事务,则已非事务性执行。
   3.PROPAGATION_MANDATORY:支持当前事务,如当前没有事务,则抛出异常(强制一定要在一个已经存在的事务中执行,业务方法不可独自发起自己的事务)。
   4.PROPAGATION_REQUIRES_NEW:始终新建一个事务,如当前原来有事务,则把原事务挂起。
   5.PROPAGATION_NOT_SUPPORTED:不支持当前事务,始终已非事务性方式执行,如当前事务存在,挂起该事务。
   6.PROPAGATION_NEVER:不支持当前事务;如果当前事务存在,则引发异常。
   7.PROPAGATION_NESTED:如果当前事务存在,则在嵌套事务中执行,如果当前没有事务,则执行与            8.PROPAGATION_REQUIRED 类似的操作(注意:当应用到JDBC时,只适用JDBC 3.0以上驱动)。


8. spring里面事务和Aop的陷阱?

        在方法里面嵌套方法,一般情况下,会是嵌套的失去对它的Aop拦截,为什么会使嵌套方法失去Aop拦截呢?(正在研究

        spring事务在多线程作用下,会失去作用(正在研究

9. spring事务与数据库事务和锁之间的关系?

           spring事务其实就是数据库事务,数据库事务其实就是数据库锁,开启spring事务意味着开启数据库默认的锁,事务隔离级别与锁之间的关系?事务的隔离级别是数据库开发商根据业务逻辑的实际需要定义的一组锁的使用策略。当我们将数据库的隔离级别定义为某一级别后如仍不能满足要求,我们可以自定义 sql 的锁来覆盖事务隔离级别默认的锁机制。

         9.1 对象锁和spring事务的对比:

             对象锁可以保证数据一致性和业务逻辑正确性,但不能保证并发性;

             spring事务不能严格保证数据一致性和业务逻辑正确性,但具有较好的并发性,因为只锁数据库行数据;

        9.2  spring事务为什么不能保证数据一致性和业务逻辑正确性:

         1. 如果事务方法抛异常,此时会回滚数据库操作,但已经执行的其他方法不会回滚,因此无法保证业务逻辑正确性;

        2 .即使事务方法不抛异常,也不能保证数据一致性(因为事务接口里的数据库操作在整个接口逻辑执行结束后才提交到数  据 库,在接口最后提交到数据库的前后很有可能带来数据一致性的问题),从而不能保证业务逻辑正确性;

         建议:

                       如果只有insert操作,可以使用事务;

                       如果涉及update操作但不涉及其他业务逻辑,可以保守使用事务;

                       如果涉及update操作及其他业务逻辑,慎用事务,

                       并且数据库查询跟数据库更新之间尽量间隔较短,中间不宜插入太多其他逻辑,减少数据一致性的风险;

                       对数据一致性要求不高的情况下可以使用事务结合乐观锁,否则建议用锁;

猜你喜欢

转载自blog.csdn.net/weixin_41629878/article/details/85133758