暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Java 多线程通过 Mybatis 获取 Oracle 序列值重复问题

全栈的程序员 2022-09-17
1568


。。


一 问题复现

orcal 可以通过  

    select equence.nextval from dual

    获取序列,作为新增表数据的主键。

    当我们批量新增的时候,我们可以使用 for循环来组装Bean集合,然后批量新增。但是我们用多线程在同一个事务内开多线程访问序列值时,会取出同一个值。本次使用的是 lambda的foreach。在循环中居然发现获取的多个序列值一样。

    二 问题原因

    在同一个事务内开多线程访问序列值时,会取出同一个值。


    三  解决办法

    1、将多线程异步循环,改为单线程循环,如 lambda的foreach 改为  普通for循环。

    2、将查询语句放在一个新事务中,同时增加同步约束。


          @Transactional(value = 'mytran', propagation = Propagation.REQUIRES_NEW, rollbackFor = {
      Exception.class })
      @Override
      public synchronized Long getNextVal() {
      return mapper.getNextVal();
      }

      注意:


      另如果在本类中调用时直接调用时事务不会生效,需要通过接口变更去调用。因为 在一个Service内部,事务方法之间的嵌套调用,普通方法和事务方法之间的嵌套调用,都不会开启新的事务.是因为spring采用动态代理机制来实现事务控制,而动态代理最终都是要调用原始对象的,而原始对象在去调用方法时,是不会再触发代理了!

      只有代理对象proxy直接调用的那个方法才是真正的走代理的。

      文章转载自全栈的程序员,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论