cstome
V2EX  ›  问与答

PHP 在高并发的时候同时写入同一条数据,会不会出现数据遗漏的问题?

  •  
  •   cstome · Jun 19, 2018 · 3060 views
    This topic created in 2904 days ago, the information mentioned may be changed or developed.

    项目 ThinkPHP+MySQL

    具体是这样,有个文章后台,每条文章有个字段存着已读人员,是数组形式存着 UID,然后 json_encode 存进数据库。

    当访问文章的时候,读取该字段,json_decode 后,判断当前 UID 是否在数组中,不存在则 push 上去,然后再 json_encode 进数据库。

    问题就是当出现高并发的时候(最高大概也就每秒上千个访问),会不会出现多个 PHP 进程同时读取了该字段,然后又同时写入数据库,导致部分数据被覆盖过去。

    同时也想知道有哪些资料可以了解一下 PHP 以及 MySQL 的线程、执行顺序问题。

    8 replies    2018-06-20 15:07:09 +08:00
    feiyuanqiu
        1
    feiyuanqiu  
       Jun 19, 2018
    跟 PHP 没关系,数据库层面可以看看悲观锁、乐观锁,小流量网站用悲观锁一般就解决了
    KgM4gLtF0shViDH3
        2
    KgM4gLtF0shViDH3  
       Jun 19, 2018 via iPhone
    用队列
    feiyuanqiu
        3
    feiyuanqiu  
       Jun 19, 2018
    不过我觉得其实应该把已读人员单独弄张表,表里面做个 文章 ID + 用户 ID 的唯一键,插入冲突就表示已经存在这个关系了,直接返回已存在的已读关系,这样接口也幂等了
    allenhu
        4
    allenhu  
       Jun 19, 2018
    每秒上千个访问, 你的 uid 字段存得下么?
    cstome
        5
    cstome  
    OP
       Jun 19, 2018
    @allenhu #4 实际情况是文章刚发布的时候会有大概最高每秒 1000 的高并发,后面会慢慢下降,UID 也不长,用 TEXT 类型完全够存。
    puritania
        6
    puritania  
       Jun 20, 2018 via iPhone
    强行制造并发……
    cstome
        7
    cstome  
    OP
       Jun 20, 2018
    @feiyuanqiu #3 之前想过这么弄,但是考虑到后面可能数据库条数比较多,影响速度,就没这么弄了。
    feiyuanqiu
        8
    feiyuanqiu  
       Jun 20, 2018   ❤️ 1
    @cstome

    怕数据库慢就用 redis,用文章表字段存这个真不太好,我现在能想到的问题就不少了:

    1. 会影响文章表的查询效率,尤其是在阅读人数变多之后,每条文章记录都平白无故增加几 K 的内容
    2. 无法检索用户已读的文章,因为是 json_encode 到 text 里面的,没法做查询,以后产品有这个需求的时候又要改又要做数据迁移
    3. 更新阅读记录效率低下,要先检索出文章,再 decode,再往里面添加内容,再 encode,再更新,还要加锁放并发;比直接插入一条阅读记录效率低多了
    4. text 的长度是 65536,你的 uid 长度是多少,假设是 32,最多可以存 2048 个 uid,实际肯定存不了这么多,因为你还做了 json_encode,也就是一篇文章上限只能存一千多个阅读记录
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5829 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 66ms · UTC 03:08 · PVG 11:08 · LAX 20:08 · JFK 23:08
    ♥ Do have faith in what you're doing.