总结了一些项目工作中的经验,顺带说一下解决问题的思路,方式倒是有很多种,看实际业务应用场景。

递归调用避免死循环问题

  • 递归坏处:由于递归需要堆栈,所以内存消耗要比非递归代码要大很多。而且,如果递归深度太大,可能系统撑不住。内存会存在突然飙升的情况。如果是数据错误导致无限循环,那问题就大了。所以这方面问题在开发的时候需要注意。
  • 解决办法:
    • 1.传递变量进行控制,比如递归50次后就结束调用,直接返回结果,使程序有终止点。
    • 2.判断传人参数合法性,是否有多处重复数据。这时可抛出异常,或return掉。抛异常的好处在于,便于捕获,做做类似健康日志监控也挺好的

解决嵌套事物

  • 这类问题的最终解决办法就是手动控制事物。
  • A类
    B类
    C类
    场景:A类 嵌套 B类 B类嵌套C类;都是由spring控制事务。
    要求:C类报异常时,不影响A类、B类的后续逻辑执行。
    问题:C类报异常,A类和B类的后续逻辑能执行,但是,数据却回滚了。
    分析:初步分析为:Spring事务控制不严格导致。由spring控制的事务,只要C类中引用的类抛出异常,那么就会标记该事务为回滚。为了避免这种情况,最好将相关类,不要让spring控制事务。

  • 方案:

    • 1.配置spring事物隔离级别:
      事务传播行为类型 || 说明
      PROPAGATION_REQUIRED || 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
      PROPAGATION_SUPPORTS || 支持当前事务,如果当前没有事务,就以非事务方式执行。
      PROPAGATION_MANDATORY || 使用当前的事务,如果当前没有事务,就抛出异常。
      PROPAGATION_REQUIRES_NEW || 新建事务,如果当前存在事务,把当前事务挂起。
      PROPAGATION_NOT_SUPPORTED || 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
      PROPAGATION_NEVER || 以非事务方式执行,如果当前存在事务,则抛出异常。
      PROPAGATION_NESTED || 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
  • 2.疑问:如何手动提交spring管理的事务?注:spring事务级别是PROPAGATION_REQUIRED

    首先在类开始部分,开启一个事务,事务的隔离级别如果是PROPAGATION_REQUIRED,手动提交事务不起作用。
    事务的隔离级别需要配置成.PROPAGATION_REQUIRES_NEW,手动提交事务才能起作用。
    //开启新事务,防止跟其他事务混淆
    DataSourceTransactionManager transactionManager = (DataSourceTransactionManager) SpringContextFactory
    .getBean(“transactionManager”);
    DefaultTransactionDefinition def = new DefaultTransactionDefinition();
    def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); //事物隔离级别,开启新事务,与A类和B类不使用同一个事务。
    TransactionStatus status = transactionManager.getTransaction(def); //获得事务状态

文章目录
  1. 1. 递归调用避免死循环问题
  2. 2. 解决嵌套事物

Sides

IT技术分享博客