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

简介: 解决高并发下insert到数据库表多条记录的问题

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条记录。问题出现了。

1.jpg

上面代码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  ) ) {

                //手动抛出异常

                throw   new   \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  ) {

                //手动抛出异常

                throw   new   \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' ;

       }


2.jpg

2.jpg8.jpg9.jpg

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


相关文章
|
12天前
|
缓存 关系型数据库 MySQL
高并发架构系列:数据库主从同步的 3 种方案
本文详解高并发场景下数据库主从同步的三种解决方案:数据主从同步、数据库半同步复制、数据库中间件同步和缓存记录写key同步,旨在帮助解决数据一致性问题。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
高并发架构系列:数据库主从同步的 3 种方案
|
26天前
|
缓存 弹性计算 NoSQL
新一期陪跑班开课啦!阿里云专家手把手带你体验高并发下利用云数据库缓存实现极速响应
新一期陪跑班开课啦!阿里云专家手把手带你体验高并发下利用云数据库缓存实现极速响应
|
3月前
|
存储 缓存 运维
优化高并发环境下的数据库查询性能:实战经验与技巧
在高并发环境下,数据库性能往往成为系统瓶颈。本文将深入探讨在高并发场景下优化数据库查询性能的策略与实践,包括索引优化、查询优化、数据库架构设计以及缓存机制的应用。通过对具体案例的分析,读者将能够掌握提升数据库性能的关键技术,从而在面对大规模用户请求时提高系统的响应速度和稳定性。
|
4月前
|
缓存 NoSQL 数据库
Redis问题之在高并发场景下,保证Redis缓存和数据库的一致性如何解决
Redis问题之在高并发场景下,保证Redis缓存和数据库的一致性如何解决
149 3
|
4月前
|
消息中间件 存储 缓存
高并发架构设计三大利器:缓存、限流和降级问题之在数据库层面确保缓存一致性问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之在数据库层面确保缓存一致性问题如何解决
|
5月前
|
消息中间件 SQL 关系型数据库
数据库如何实现读写分离以应对高并发?
【6月更文挑战第17天】数据库如何实现读写分离以应对高并发?
79 1
|
5月前
|
存储 缓存 数据处理
数据库高并发
【6月更文挑战第17天】数据库高并发
66 1
|
4月前
|
缓存 数据库
高并发场景下,到底先更新缓存还是先更新数据库?
高并发场景下,到底先更新缓存还是先更新数据库?
|
6月前
|
JavaScript 数据库
❤Nodejs 第七章(操作本地数据库高并发createPool方式)
【4月更文挑战第7天】本文介绍了如何使用Node.js操作本地数据库接口的优化,将之前的单次连接(createConnection)替换为支持高并发的连接池(createPool)。主要改动包括:查询、新增用户、获取用户详情、更新和删除用户的方法,都改用`connectionpool.query()`。这样改进能提升效率,适应更多并发请求。代码示例展示了如何在路由处理函数中使用连接池进行数据库操作。
200 6
❤Nodejs 第七章(操作本地数据库高并发createPool方式)
|
5月前
|
缓存 NoSQL Java
高并发场景下缓存+数据库双写不一致问题分析与解决方案设计
高并发场景下缓存+数据库双写不一致问题分析与解决方案设计

热门文章

最新文章

  • 1
    高并发场景下,到底先更新缓存还是先更新数据库?
    64
  • 2
    Java面试题:解释Java NIO与BIO的区别,以及NIO的优势和应用场景。如何在高并发应用中实现NIO?
    70
  • 3
    Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
    66
  • 4
    Java面试题:如何实现一个线程安全的单例模式,并确保其在高并发环境下的内存管理效率?如何使用CyclicBarrier来实现一个多阶段的数据处理任务,确保所有阶段的数据一致性?
    61
  • 5
    Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
    53
  • 6
    Java面试题:假设你正在开发一个Java后端服务,该服务需要处理高并发的用户请求,并且对内存使用效率有严格的要求,在多线程环境下,如何确保共享资源的线程安全?
    68
  • 7
    在Java中实现高并发的数据访问控制
    41
  • 8
    使用Java构建一个高并发的网络服务
    27
  • 9
    微服务06----Eureka注册中心,微服务的两大服务,订单服务和用户服务,订单服务需要远程调用我们的用,户服务,消费者,如果环境改变,硬编码问题就会随之产生,为了应对高并发,我们可能会部署成一个集
    37
  • 10
    如何设计一个秒杀系统,(高并发高可用分布式集群)
    127