mysql高并发insert_解决高并发下insert到数据库表多条记录的问题

在高并发场景下,通过检查openid并插入数据可能导致数据库出现多条重复记录。通过引入MySQL事务和行级锁,可以避免这个问题。在事务中使用`lock(true)`锁定查询行,确保在事务提交前其他并发请求无法修改数据,从而防止并发插入。另外,设置唯一索引也是防止重复插入的有效方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.有种业务场景比如微信会员注册,我们首先判断openid在数据库表中是否存在如果存在则提示已经存在,否则注册一条会员记录。thinkphp5代码如下

$openid='1111111';

//查询openid是否存在

$info=Db::table('test')->where('openid',$openid)->find();

if(!empty($info)) {

echo'openid已经存在!';

die;

}

sleep(2);//模拟其他复杂业务逻辑处理增加耗时

//insert插入

$data['openid'] =$openid;

$data['add_time'] =date('Y-m-d H:i:s',time() );

$rs=Db::table('test')->insert($data);

print_r($rs);

die;

我相信这样的场景有很多,而且大家也都写过类似的代码,而且看上去也在正常不过了,但是这样的代码在高并发的情况下会插入数据库表多条记录。

我用apache jmeter压测工具模拟50个并发请求,然后发现数据库进来25条记录。问题出现了。295cf8b1c3eb22b3701a58dca6cd4f57.png

上面代码sleep(2);是为了模拟注册过程中其他的一些业务逻辑处理。如果没有sleep(2),我用apache jmeter工具并发请求,也没有发现出来多条记录。那么如果解决上面的问题呢?引入mysql锁的概念。锁必须与事务配合使用下面是改进的代码 :

$openid='1111111';

// 启动事务

$trans_result=true;

Db::startTrans();

try{

//查询openid是否存在  ,//查询之后锁住该条记录让其他程序无法修改,直到事务提交释放锁

$info=Db::table('test')->lock(true)->where('openid',$openid)->find();

if( !empty($info) ) {

//手动抛出异常

thrownew\Exception('openid已经存在!');

}

sleep(2);

//模拟其他复杂业务逻辑处理增加耗时

//insert插入

$data['openid'] =$openid;

$data['add_time'] =date('Y-m-d H:i:s',time() );

$rs=Db::table('test')->insert($data);

if( !$rs) {

//手动抛出异常

thrownew\Exception('insert 失败!');

}

Db::commit();

}catch( \Exception$e) {

// 回滚事务

Db::rollback();

$trans_result=false;

echo$msg=$e->getMessage();

}

//如果失败

if( !$trans_result) {

echo'执行失败0'.$msg;

}else{

echo'执行成功1';

}

cd34abc45d76e524e3097103a1045a92.pngc20778a512ccb4728de6c1fd4f0ade5d.png9ad0c203e6de5f18cc56fcf86661a7da.png

总结,把查询语句和插入语句放到一个事务里面,解决不了并发插入多条记录的问题,还需要配置使用锁,锁的意思就是当n个请求同时过来只有一个人能获取到锁,并且锁住那条记录,其他程序无法获取到就会报错,也就是这么多并发请求,最终只有一个能够执行成功。当然此案例也可以使用mysql表openid字段设置唯一索引,50个并发最终也会只有一个能成功,其他的同样会抛出sql异常。

版权声明:若无特殊注明,本文皆为《菜鸟站长》原创,转载请保留文章出处。

本文链接:解决高并发下insert到数据库表多条记录的问题 - https://www.wlphp.com/?post=248

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值