PHP 在高并发下,怎么正确处理,才能保持数据的一致性?

2018 年 3 月 15 日
 madaima

//流程一
class Factory
{
    public static function get($item)
    {
        switch ($item->status){
            case 1;
                return new a($item);
            case 2;
                return new b($item);
            ...
        }
    }
}

//流程二
class  a
{
    public function aa($item)
    {
        //DB BEGIN
        //set status = 2
        //DB COMMIT
        //catch DB ROLLBACK
    }
}

首先我们排除使用悲观锁这种方法。

如代码所示,现在处理数据时会先进入工厂类判断数据状态,然后到不同的类中去处理数据。

但是在高并发下,流程二没走完的情况下,数据状态没更新,第二次请求还会走到流程二中去处理。

这种情况 有什么好的方法去处理?

8109 次点击
所在节点    PHP
36 条回复
onepunch
2018 年 3 月 15 日
Redis 锁,感觉 aa 应该被保护起来吧 ,如果并发很容易就达到 aa,那么数据库的压力还是很大的吧。

战略 mark 下
yao978318542
2018 年 3 月 15 日
队列?我觉得可以吧
RorschachZZZ
2018 年 3 月 15 日
目前我用队列来解决,坐等高手回答 码之
lqtriks
2018 年 3 月 15 日
Mark.
prolic
2018 年 3 月 15 日
redlock 了解一下
kobe123
2018 年 3 月 15 日
异步 work
Xrong
2018 年 3 月 15 日
楼主弄完,分享下方案撒。
wekw
2018 年 3 月 15 日
1. 分布式系统的核心功能是“队列消息传递”。
2. 并发量不太高的时候,用原子化锁:redis 字段标记。
3. 并发量太高的时候就得时间换性能了:用高性能消息队列。本质依然是原子化,不过将简单的标记又抽象成了队列数据存储+后期执行,实现了单机更高性能。
4. 当单机消息队列都扛不住的时候就要上真正的分布式消息队列了,如 kafka
90safe
2018 年 3 月 15 日
@qfdk 来研究这个啊,整天研究速度优化有啥用
youqiantu
2018 年 3 月 15 日
高并发 redis 也不行啊。。。
shisang
2018 年 3 月 15 日
乐观锁
liuxu
2018 年 3 月 15 日
要不楼主别两次 get,直接 case1 执行完后回调 case2?
vtwoextb
2018 年 3 月 15 日
队列
afeicool
2018 年 3 月 15 日
不知道是不是我的理解能力太弱,完全没看懂你的业务,如果只是改状态的话 完全可以用 set status=2 where status = 1, 何必又是这个锁那个队列,甚至跑到分布式上去了…
madaima
2018 年 3 月 16 日
@afeicool 这里只是举个大概的流程,每个流程里面有很多业务方法,单改变状态的话就没有这么复杂了。
th00000
2018 年 3 月 16 日
redis 串行
否则 乐观锁 悲观锁

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://study.congcong.us/t/438205

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX