zoukankan      html  css  js  c++  java
  • 多线程调用生成主键流水号存储过程产生主键冲突问题解决方案

    遇到开发多线程测试插入数据的时候发现主键冲突问题

    具体描述如下:

    --------------------------------------------------------------

    调用Procedure_insert

    Procedure_insert

    Begin

    Call procedure(获取流水号)

    Insert into table values(流水号作为id,其他列);

    End

    流水号存储过程:

    Update 统计表 统计字段+1

    Update 统计表 最终流水号 set类型+年月日+补零位+统计字段

    Select 最终流水号; //作为主键

    --------------------------------------------------------------- 

    问题:多线程并发会生成的主键冲突

    写个java多线程调用一下测试,发现当加上事务便不会出现问题,无论在存储过程加还是代码过程加事务都可以,看似问题就这么解决了,方案如下:

    -----------------------------------------------------------------

    程序代码  con.begin 开始事务

    调用Procedure_insert

    Procedure_insert

    Begin

    Call procedure(获取流水号)

    Insert into table values(流水号作为id,其他列);

    End

    程序代码 con.commit();

    流水号存储过程:

    Update 统计表 统计字段+1

    Update 统计表 最终流水号 set类型+年月日+补零位+统计字段

    Select 最终流水号; //作为主键

    -----------------------------------------------------------------

    不过问题究竟发生在哪里,既然是主键冲突,并且只有在多线程并发下,没有事务的情况下才会发生,那么单独测试一下生成主键的存储过程,如下:

    发现问题了,果然是多线程下没加事务造成的

    既然测试出来结果,也知道了解决方法,貌似就解决了,那么又有新的问题了,为什么不加事务多线程调用生成流水号的存储过程会产生相同的主键呢?

    和我的流水号生成方式有关

    procedure

    begin

    update 语句;

    update 语句 拼接;

    select 语句;

    end

    由于多线程并发,导致更新流水号时是异步的,第一个语句可能同时执行了,然后再执行第二句,导致最终只会产生最后一个主键;总之生成主键的过程并不是一个整体,导致了生成同一个主键。

  • 相关阅读:
    5步教你完成小熊派开发板贴片
    了解JS压缩图片,这一篇就够了
    【华为云推官招募】加入云推官,月入8万的兼职不是梦
    JavaScript中的正则表达式详解
    一瓶可乐的自动售货机指令“旅程”
    年近而立,Java何去何从?
    数据平台、大数据平台、数据中台……你确定能分得清吗?
    微软看上的Rust 语言,安全性真的很可靠吗
    云图说丨手把手教你为容器应用配置弹性伸缩策略
    Spark优化之小文件是否需要合并?
  • 原文地址:https://www.cnblogs.com/jiangwenju/p/4974675.html
Copyright © 2011-2022 走看看