重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章将为大家详细讲解有关如何解决PHP+MySQL高并发加锁事务处理的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
为准格尔等地区用户提供了全套网页设计制作服务,及准格尔网站建设行业解决方案。主营业务为网站制作、成都网站制作、准格尔网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!具体如下:
1、背景:
现在有这样的需求,插入数据时,判断test表有无username为‘mraz'的数据,无则插入,有则提示“已插入”,目的就是想只插入一条username为‘mraz'的记录。
2、一般程序逻辑如下:
$conn = mysqli_connect('127.0.0.1', 'root', '111111') or die(mysqli_error()); mysqli_select_db($conn, 'mraz'); $rs = mysqli_query($conn, 'SELECT count(*) as total FROM test WHERE username = "mraz" '); $row = mysqli_fetch_array($rs); if($row['total']>0){ exit('exist'); } mysqli_query($conn, "insert into test(username) values ('mraz')"); var_dump('error:'.mysqli_errno($conn)); $insert_id = mysqli_insert_id($conn); echo 'insert_id:'.$insert_id.'
'; mysqli_free_result($rs); mysqli_close($conn);
3、一般少量请求的时候,程序逻辑不会有问题。但是一旦高并发请求执行的话,程序并没有按预期执行,会插入多条username为‘mraz'的记录。
4、解决方案:利用mysql的FOR UPDATE 语句和事务的隔离性。注意的是FOR UPDATE仅适用于InnoDB,且必须在事务(BEGIN/COMMIT)中才能生效。
调整代码后如下:
$conn = mysqli_connect('127.0.0.1', 'root', '111111') or die(mysqli_error()); mysqli_select_db($conn, 'mraz'); mysqli_query($conn, 'BEGIN'); $rs = mysqli_query($conn, 'SELECT count(*) as total FROM test WHERE username = "mraz" FOR UPDATE'); $row = mysqli_fetch_array($rs); if($row['total']>0){ exit('exist'); } mysqli_query($conn, "insert into test(username) values ('mraz')"); var_dump('error:'.mysqli_errno($conn)); $insert_id = mysqli_insert_id($conn); mysqli_query($conn, 'COMMIT'); echo 'insert_id:'.$insert_id.'
'; mysqli_free_result($rs); mysqli_close($conn);
5、再利用php的curl模拟高并发请求该php脚本,查看数据库会只有一条username为‘mraz'的记录。达到程序执行的预期结果~
关于“如何解决PHP+MySQL高并发加锁事务处理的问题”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。