PHP多线程数据交叉存储 防止读取重复数据

       今天碰到一个问题,PHP执行计划任务的时候出现了数据多次占用的问题。(首先声明代码是绝对没问题的。)


       事例,程序中计划任务获取程序运单号推送订单到快递公司,每两个小时自动执行这个计划任务。但是这样就可能会导致一个问题:暂且把第一次调用这个计划任务叫做任务A,第二次叫做任务B。

       A执行的时候没有问题,但是可能执行A所花的时间比较长(本来需要时间很短,但受到各种因素影响),B开始执行的时候A还没执行完,所以可能导致B和A读取相同的运单号进行操作,这个时候就会导致部分运单号会多次调用,有些运单号使用了两次。


解决这个问题这里有三种方式:

       第一种:增加间隔时长。两次计划任务执行的时间间隔尽可能的长,让他们不会有交集,也就不会有重叠。

       第二种:提前声明占用。A执行读取一个运单号立马标记该运单已经使用,判断是否推送成功的操作延后执行,运单已经占用了,就算A和B重叠B也不会使用A使用的运单号(因为已经打上标记了),后面判断推送结果,如果A推送失败了则释放A占用的运单号,如果推送成功则不用操作。

       这种方法有个缺陷:读取运单号后更新数据库需要一定的时间(虽然很段,但是确实存在),而且数据库服务器可能在处理其他的请求,加大了更新延时。计算机处理程序非常快,所以这个问题就更加明显。相比更新数据库,一个好点的方法就是读取运单号后立即放入 $_SEEEION 超全局变量中,下次查询运单号时排除 $_SESSION 变量中的数据,这样较更新数据库可以缩短一定的时间。

       第三种:给方法加锁机制。进入方法的时候给方法加锁,加锁后拒绝下次请求该方法的进程,进入等待模式。


       文件锁:自定义一个文件作为锁文件。每次进入该方法的时候,读取该文件,打开成功后给文件加锁,如果加锁成功则执行读取运单号方法,如果加锁失败(因为已经被其他进程锁住)则进入等待模式或者直接退出方法。加锁成功后执行相应的操作,所有操作执行完毕后释放文件锁,下个进程就可以访问该方法。

       该方法是通过给文件加锁,判断文件是否已经锁住来判断方法是否已经被调用。


       不知道能不能直接给方法加锁,调用方法就标记方法已经被调用来。如果定义一个常量,进入该方法就把这个常量标记成 true 表示已经被调用,false 表示未被调用。当变量为 ture 时不执行方法里面的逻辑代码段,为 false 才执行。直到最后一行代码方法执行完毕时把常量置成 false 允许下个进程访问。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值