PHP curl zamanlama uyumsuzluğu

3 Cevap php

Ben bir php komut dosyası çalıştıran ediyorum:

  1. bir miktar almak için yerel bir veritabanı sorguları
  2. Yukarıda miktarı + x ile harici bir veritabanını güncellemek için bir kıvırmak deyimi yürütür
  3. kıvırmak deyimi idam edildiğini yansıtan yeni bir satır eklemek için tekrar yerel veritabanını sorgular.

Ben yaşıyorum sorunlardan biri kıvırmak deyimi yürütmek için 2-4 saniye sürer, bu yüzden aynı anda aynı komut dosyası çalıştıran aynı şirketten iki farklı kullanıcıların olması, kıvırmak komutun yürütme zamanı neden olabilir dış veritabanında güncellenir ne olması gerektiğini uyumsuzluğa. Kıvırmak deyimi henüz ilk kullanıcı dönmedi ... bu yüzden ikinci bir kullanıcı yanlış rakamlar kapalı çalışıyor, çünkü bu olduğunu.

Ben burada en iyi seçeneklerden emin değilim, ama temelde aynı anda yürütülüyor iki veya daha fazla kıvırmak ifadeleri önlemek gerekir.

Ben kıvırmak deyimi o anda yürütülmekte olduğunu gösterir veritabanında bir değeri saklamak düşündüm ve onun tamamlanana kadar yürütülüyor başka kıvırmak ifadeleri engellemek. İlk kıvırmak deyimi idam edildikten sonra, daha sonra veritabanı bayrağı güncellenir ve bir sonraki çalıştırabilirsiniz. Bu alan 'kilitli' ise, o zaman (5) saniye boyunca kodu ve uyku aracılığıyla döngü olabilir, ve bayrağı sıfırlamak olup olmadığını tekrar kontrol edin. (3) döngüler sonra, sonra (ben curl 5 saniyeden daha uzun sürer görmedim) otomatik bayrağı sıfırlamak ve işleme devam edin.

Bu yaklaşan başka (daha şık) yolları var mı?

3 Cevap

Sen flock keyfi dosyası ile kullanabilirsiniz. Bu kilidi edinebilirler kadar bu şekilde, ikinci komut engeller.

$lockfile = 'foo.bar';
$fd = fopen($lockfile, "w");
if (flock($fd, LOCK_EX)) {
    do_your_stuff();
}
else
    die("error"); //should not happen; flock should block until the lock is acquired

fclose($fd);

EDIT:

PHP dağıtılmış işlemleri uygulamak için basit bir yolu yoktur, Java EE değildir.

İhtiyacınız ne denir Concurrency control. Birçok insan bu konuyu araştırma içine zaman ve çaba koyarak edilmiştir.

Bu sorun öyle umut gibi basit değildir. Bazı forum motorlar (cough Stackoverflow cough) da buna benzer bir şey uygulamak, bu yüzden onlar oluşturuldukları sırayla mesajları gösterebilir (yapmadı). Bu son kullanıcı hala etkin ve hala şu anda zaman zaman, eklenen / düzenlenen ediliyor kaydını işlerken sunucuyu bildirmek için kullanılacak olan rastgele bir belirteç oluşturarak yapılır. Bu birlikte en sık görülen sorunlar bağlantı zaman aşımı ve kullanıcı zaman aşımı konulardır. Bağlantı zaman aşımı istemci heartbeat (web üzerinde bu genellikle sadece bağlantı hala alive olduğu sunucuyu bildirmek için bir HTTP isteği düzenlenmek suretiyle yapılır göndermek suretiyle tespit edilir - Düzenli aralıklarla sunucuya) açık; istemci uzun bir süre için hearbeats göndermeyi durdurur, eğer sunucu tarafından aşımına kabul edilir. Aynı zamanda, müşteri de heartbeat sunucu ya ulaşmıştır ve bu durumda ne yapılması düşünmelisiniz eğer bağlantı zaman aşımına uğradı farkında olmalıdır. Orada kullanıcı sadece bir kaydı kilitler kullanıcı zaman aşımı durum, aynı zamanda ve uzun bir süre için bilgisayar bırakır. Bu durumda, istemci ve sunucu hem de kayıt kilitli olmuştur ama o (düzenlenmiş) kullanılan henüz uzun bir süre ve her ikisi de harekete geçmesi gerektiğini bilincinde olmalıdır.

Sorun tek bir cümleyle formüle edilebilir, basit görünebilir, ama cevabı çok karmaşık ve pek çok faktöre bağlıdır.

kıvırmak) (curl_multi_exec N kaynaklara paralel istekleri destekler. Eğer sıralı (birden curl_ * çağrıları hangi arasında) bu çağrıları yapmak ve yukarıdaki ifadeler yapmak istiyorsanız bir atomik işlem bunu kullanırken durumda curl_multi kullanmayın.

Eğer güncelleme (ler) için erişim veritabanı kayıtları (ya da olmamalı), aynı anda birden fazla 1 kullanıcı (lar) tarafından erişilebilir olamaz o zaman kilitleme / işlemleri eğer Database Server edinilebilir düşünmelisiniz.

(Daha fazla bilgi için google damgalarını kullanarak sahte işlemler için bir yöntem var) Eğer dediğiniz gibi 'kilitli' gibi bir kayıt işaretleme bir sütun ile bir pseudo-işlem mekanizmasının kullanılması size yardımcı olabilir ama ben kesin olamaz.