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

2018-03-15 10:05:13 +08:00
 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
    }
}

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

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

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

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

6940 次点击
所在节点    PHP
36 条回复
onepunch
2018-03-15 11:43:44 +08:00
Redis 锁,感觉 aa 应该被保护起来吧 ,如果并发很容易就达到 aa,那么数据库的压力还是很大的吧。

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

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

https://www.v2ex.com/t/438205

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

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

© 2021 V2EX