高并发下如何必免不停的插入数据库?

从此不换网名 2021-04-05 10:44:09
场景
同一个会话一次性,提交多条数据,其中业务场景只需执行一条增加记录后,就开始执行后往的代码,但现在是他会同并发多少条就增加多少记录,请问大伙这个有什么好的办法解决。


session_start();

if (!isset($_SESSION['gu_id'] ))
{
$_SESSION['gu_id'] = mt_rand(5, 15);//只要是同一会话进来的不管是多少并发他的ID值都是一样,但现在他会有多少个并发他的ID就会有多少
$gu_id = $_SESSION['gu_id'];
}else{
$gu_id = $_SESSION['gu_id'];
}
INSERT INTO tb1 (` id`, `name`, )
VALUES
( $gu_id, 'name1' );//不管有多少个并发只插入一条数据

//以下还有其他业务代码



各位,如何实现,同一会话不管是多少个并发只生成一个ID,只插入一条数据?
...全文
2798 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
从此不换网名 2021-04-21
  • 打赏
  • 举报
回复
引用 34 楼 xd� 的回复:
可以使用对待秒杀接口的方法 单机服务可以直接在开头加个用localcache的increase>1 跳过存gu_id操作, key可以你直接用session_id加点特别标识 多服务就用redis.increase>1做原子性操作判断 执行完下面业务逻辑后你再把这个key的缓存数据删掉,这样就不会留垃圾缓存数据 其实你就是想gu_id这个在第一次大并发时只存一个,那就加个拦截就好,可用的方法很多的
有什么方法呢
战场的咕哒子 2021-04-20
  • 打赏
  • 举报
回复
可以使用对待秒杀接口的方法 单机服务可以直接在开头加个用localcache的increase>1 跳过存gu_id操作, key可以你直接用session_id加点特别标识 多服务就用redis.increase>1做原子性操作判断 执行完下面业务逻辑后你再把这个key的缓存数据删掉,这样就不会留垃圾缓存数据 其实你就是想gu_id这个在第一次大并发时只存一个,那就加个拦截就好,可用的方法很多的
家有萌宝V 2021-04-17
  • 打赏
  • 举报
回复
感觉不是代码的问题, 是设计模式没弄对,并发情况下要保证数据正确性需要加上缓存设计。
xiaoxiangqing 2021-04-13
  • 打赏
  • 举报
回复
可以用redis
我在地球 2021-04-12
  • 打赏
  • 举报
回复
程序里面可以用临界区控制进入数据库的操作;数据库操作可以考虑使用存储过程,插入数据前先查询唯一标识。
头咯哇咯哇 2021-04-10
  • 打赏
  • 举报
回复
..
小灰狼 2021-04-09
  • 打赏
  • 举报
回复
你的业务功能需要插入数据到表里,那就得插,你为何要避免呢?
xinganjue333 2021-04-09
  • 打赏
  • 举报
回复
那你怎么判断是不是同一会话?
luj_1768 2021-04-09
  • 打赏
  • 举报
回复
是做区块链的吧?服务器把你当成矿工了。区块服务刚好也需要id 资源。
xuzuning 2021-04-08
  • 打赏
  • 举报
回复
你只是 if (!isset($_SESSION['gu_id'] )) 当然是不行的 要比较 $_SESSION['gu_id'] 的值!
圣殿骑士18 2021-04-08
  • 打赏
  • 举报
回复
引用 22 楼 圣殿骑士18 的回复:
java和c#中都有lock关键字,来解决这个问题。 查查php有信号量机制吗?
https://www.cnblogs.com/jkko123/p/6294595.html
圣殿骑士18 2021-04-08
  • 打赏
  • 举报
回复
java和c#中都有lock关键字,来解决这个问题。 查查php有信号量机制吗?
zengshengkai 2021-04-08
  • 打赏
  • 举报
回复
学些东西学些东西
  • 打赏
  • 举报
回复
好 很好.......
666_666 2021-04-07
  • 打赏
  • 举报
回复
引用 11 楼 从此不换网名 的回复:
现在做了这样的判断就插入数据库时就会提示KEY重复了



 if (isset($_SESSION['gu_id'])) 
 {
          // 
           $gu_id = $_SESSION['gu_id'];
             //查询一下数据库有没有存在,只要用了这个判断在拼发的时候就会提示主健重复
             $un = SELECT * FROM `sys_filegroup` WHERE `id` = $gu_id;
              if (count($un) == 0) 
              {
                 INSERT INTO tb1 (` id`, `name` ) VALUES ( $gu_id, 'name1' );
              }

          }else{
             $_SESSION['gu_id'] =  mt_rand(5, 15);
             $gu_id = $_SESSION['gu_id'] ;
             INSERT INTO tb1 (` id`, `name` ) VALUES (    $gu_id, 'name1' );
          }
如果只是想高并发下,获取id只是一条,可以用insert ignore into new_test()VALUES()条语句
从此不换网名 2021-04-07
  • 打赏
  • 举报
回复
引用 18 楼 666_666 的回复:
[quote=引用 16 楼 从此不换网名 的回复:][quote=引用 14 楼 666_666 的回复:][quote=引用 11 楼 从此不换网名 的回复:]现在做了这样的判断就插入数据库时就会提示KEY重复了



 if (isset($_SESSION['gu_id'])) 
 {
          // 
           $gu_id = $_SESSION['gu_id'];
             //查询一下数据库有没有存在,只要用了这个判断在拼发的时候就会提示主健重复
             $un = SELECT * FROM `sys_filegroup` WHERE `id` = $gu_id;
              if (count($un) == 0) 
              {
                 INSERT INTO tb1 (` id`, `name` ) VALUES ( $gu_id, 'name1' );
              }

          }else{
             $_SESSION['gu_id'] =  mt_rand(5, 15);
             $gu_id = $_SESSION['gu_id'] ;
             INSERT INTO tb1 (` id`, `name` ) VALUES (    $gu_id, 'name1' );
          }
如果只是想高并发下,获取id只是一条,可以用insert ignore into new_test()VALUES()条语句 [/quote] $_SESSION['gu_id'] = mt_rand(5, 15); 这个随机数一并发就会出现不同的ID了,所以有这个 insert ignore into new_test()VALUES() 也同样会插入多条的, 现在是 如何在高并发下 保障 $_SESSION['gu_id'] = mt_rand(5, 15); 只运行一下且只插入一条数据。[/quote] 提交数据时,监测点击事件,将按钮至灰或者隐藏[/quote] API接口调用,跟前端没关系
666_666 2021-04-07
  • 打赏
  • 举报
回复
引用 16 楼 从此不换网名 的回复:
[quote=引用 14 楼 666_666 的回复:][quote=引用 11 楼 从此不换网名 的回复:]现在做了这样的判断就插入数据库时就会提示KEY重复了



 if (isset($_SESSION['gu_id'])) 
 {
          // 
           $gu_id = $_SESSION['gu_id'];
             //查询一下数据库有没有存在,只要用了这个判断在拼发的时候就会提示主健重复
             $un = SELECT * FROM `sys_filegroup` WHERE `id` = $gu_id;
              if (count($un) == 0) 
              {
                 INSERT INTO tb1 (` id`, `name` ) VALUES ( $gu_id, 'name1' );
              }

          }else{
             $_SESSION['gu_id'] =  mt_rand(5, 15);
             $gu_id = $_SESSION['gu_id'] ;
             INSERT INTO tb1 (` id`, `name` ) VALUES (    $gu_id, 'name1' );
          }
如果只是想高并发下,获取id只是一条,可以用insert ignore into new_test()VALUES()条语句 [/quote] $_SESSION['gu_id'] = mt_rand(5, 15); 这个随机数一并发就会出现不同的ID了,所以有这个 insert ignore into new_test()VALUES() 也同样会插入多条的, 现在是 如何在高并发下 保障 $_SESSION['gu_id'] = mt_rand(5, 15); 只运行一下且只插入一条数据。[/quote] 提交数据时,监测点击事件,将按钮至灰或者隐藏
从此不换网名 2021-04-07
  • 打赏
  • 举报
回复
引用 14 楼 666_666 的回复:
[quote=引用 11 楼 从此不换网名 的回复:]现在做了这样的判断就插入数据库时就会提示KEY重复了



 if (isset($_SESSION['gu_id'])) 
 {
          // 
           $gu_id = $_SESSION['gu_id'];
             //查询一下数据库有没有存在,只要用了这个判断在拼发的时候就会提示主健重复
             $un = SELECT * FROM `sys_filegroup` WHERE `id` = $gu_id;
              if (count($un) == 0) 
              {
                 INSERT INTO tb1 (` id`, `name` ) VALUES ( $gu_id, 'name1' );
              }

          }else{
             $_SESSION['gu_id'] =  mt_rand(5, 15);
             $gu_id = $_SESSION['gu_id'] ;
             INSERT INTO tb1 (` id`, `name` ) VALUES (    $gu_id, 'name1' );
          }
如果只是想高并发下,获取id只是一条,可以用insert ignore into new_test()VALUES()条语句 [/quote] $_SESSION['gu_id'] = mt_rand(5, 15); 这个随机数一并发就会出现不同的ID了,所以有这个 insert ignore into new_test()VALUES() 也同样会插入多条的, 现在是 如何在高并发下 保障 $_SESSION['gu_id'] = mt_rand(5, 15); 只运行一下且只插入一条数据。
从此不换网名 2021-04-07
  • 打赏
  • 举报
回复
引用 13 楼 下雨的声音丶 的回复:
[quote=引用 12 楼 从此不换网名 的回复:][quote=引用 10 楼 下雨的声音丶 的回复:][quote=引用 9 楼 从此不换网名 的回复:][quote=引用 8 楼 下雨的声音丶 的回复:][quote=引用 7 楼 从此不换网名 的回复:][quote=引用 6 楼 下雨的声音丶 的回复:]那你怎么判断是不是同一会话?
通过 session[/quote] 你说的session_id会变啊,怎么还能通过session?[/quote] session_id 不会变 mt_rand(5, 15) 在高并发时这个就会变了,我现在如何确保他只执行一次 [/quote] 你session_id 不变 那这个就只会执行一次啊


session_start();

if (!isset($_SESSION['gu_id'] )) {
    $_SESSION['gu_id'] =  mt_rand(5, 15);//只要是同一会话进来的不管是多少并发他的ID值都是一样,但现在他会有多少个并发他的ID就会有多少
    INSERT INTO tb1 (` id`, `name` ) VALUES (  $_SESSION['gu_id'], 'name1' );//不管有多少个并发只插入一条数据
}
$gu_id =  $_SESSION['gu_id'];

[/quote] 这个方法试了很多次,同一会话 同时请求5个时 同样也会插入5条数据,并发的速度比 session处理的快[/quote] 那是因为 第一次请求的时候没有建立会话,你同时请求5个的话,会建立5次。当然会重复。 你试一试先请求一次把会话建立起来,后面再请求多次看看 [/quote] 第一次请求时就并发了,如何能建立会话呢
下雨的声音丶 2021-04-06
  • 打赏
  • 举报
回复

session_start();

if (!isset($_SESSION['gu_id'] )) {
    $_SESSION['gu_id'] =  mt_rand(5, 15);//只要是同一会话进来的不管是多少并发他的ID值都是一样,但现在他会有多少个并发他的ID就会有多少
    INSERT INTO tb1 (` id`, `name` ) VALUES (  $_SESSION['gu_id'], 'name1' );//不管有多少个并发只插入一条数据
}
$gu_id =  $_SESSION['gu_id'];
这样不就行了? 所说的同一会话 就是相同的session_id吧
加载更多回复(12)

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧