java嵌套事物与递归调用避免死循环问题

    作者:课课家教育更新于: 2015-12-18 15:50:31

    大神带你学编程,欢迎选课

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

    java嵌套事物与递归调用避免死循环问题-课课家教育

      递归调用避免死循环问题

      递归坏处:由于递归需要堆栈,所以内存消耗要比非递归代码要大很多。而且,如果递归深度太大,可能系统撑不住。内存会存在突然飙升的情况。如果是数据错误导致无限循环,那问题就大了。所以这方面问题在开发的时候需要注意。

      解决办法:

      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