mysql 多线程 主键_多线程调用生成主键流水号存储过程产生主键冲突问题解决方案...

在多线程环境下,通过存储过程生成主键流水号时出现冲突。问题在于并发更新流水号时未使用事务,导致主键重复。通过在Java代码中开启事务并提交,确保存储过程中的流水号生成为一个原子操作,从而避免主键冲突。问题根源是更新流水号的两个步骤在多线程中可能异步执行,造成主键生成不一致。
摘要由CSDN通过智能技术生成

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

问题具体描述如下:

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

调用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 最终流水号; //作为主键

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

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

76593864086f16c70bf3ab826fd9d907.png

b27ff9b10f0d208dad2b1897edb62768.png

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

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

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

procedure

begin

update 语句;

update 语句 拼接;

select 语句;

end

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值