并发访问、事务安全,蛋疼的Bug

上线的系统出了个Bug,数据库出现了脏数据,做了一半的事务居然提交了,觉得有点不可思议。但是不可思议的事情居然还大量发生了。

检查相关功能,Bug功能出现在一个自己实现的cron机制触发的定时任务中。由于PHP没有常驻系统的机制,因此计划任务或者定时任务这种东西只能依靠流量驱动,或者利用Linux系统的CRON服务。为了不增加运维人员的维护压力,就选择了前者,使用流量来驱动定时任务检查和触发。

结果,悲剧鸟。

大量请求到来的时候,如所料的触发了计划任务,但是计划任务的执行被并发了(我错误地估计了流量,比预想的要大得多)。

计划任务中已经开启了数据库的事务安全,但依然没能挡住脏数据入侵数据库。

看来这儿必须得进行更加严格的处理了。

目测现在有三种方法实现进程同步:

flock – 文件加锁,优点是简单易行,缺点是不能分布式,高并发时锁不住,还容易造成死锁。

sysvsem/shmop – Unix上的IPC和共享内存机制,比较好使的加锁机制,但是仅限Unix*平台,而且有可能服务器不支持。

借助第三方的扩展,什么eAccelerator,xcache这种优化器,提供的缓存或者锁机制。优劣不好评价。

或者从根本上避免并发访问,cron任务的启动不依赖于访问请求,这样最好了。但是就得在crontab里面加入curl这种东西了。

一直觉得PHP这货是从来不用考虑并发安全问题的,现在觉得想法太幼齿了啊。。。