Açık / beklemede hareketi olan bir DB tablosunu güncelleştirmek için bir PHP komut dosyası kullanarak süresiz engelleme önlemek için nasıl?

2 Cevap php

Ben SQLplus üzerinden tablo X değiştirmek ve değişikliği taahhüt yoksa, o zaman (ModPHP modunda Apache altında bir PHP komut dosyası olarak çalışır) benim web appliation o kadar belirsiz bir süre bloke edecek tablo X bir değişiklik taahhüt denerse bulduk Ben SQLplus ile benim değişiklikleri işlemek.

Bu davranış doğru, ama ne istediğinizi N saniye sonra benim web uygulaması zaman aşımı var ve yerine süresiz engelleme HTTP 409 hata yayma temiz / güvenilir / basit bir yoludur.

Benim ilk düşünce N saniye sonra SIGALRM yakalamak için bir sinyal işleyici ile pcntl_alarm (N) kullanımı idi. Ama o pcntl_ * fonksiyonlar genellikle kök Apache sürecinin kendisi çocukları kontrol etmek için kullandığı sinyalleri karıştırmasını önlemek için muhtemelen, böylece derleme zamanında ModPHP Apache modülünden elided bulundu. Belki ought kendi SIGARLMs işlemek için ModPHP üzerinden çalıştırmak PHP için Zararsız olması, ama ben şu anda benim Ops ekibi ile almak istiyorum, bu yüzden bu yaklaşımı reddetmek zorunda bir mücadele değil.

Operasyonu (başarılı) veya N saniye bitene kadar benim ikinci düşünce çatal / Bir çocuk işlemini benim uygulama tablo X değiştirmek için ihtiyacı her zaman başlatmak ve ana süreç poll (bir boru belki select üzerinden ()) çocuk sahibi olmaktır (zaman aşımı + yetmezliği) geçti.

İkinci yaklaşım will iş, ama bu bana, çirkin karmaşık ve kırılgan vurur.

Herkes (Linux 2.6.9 üzerine) PHP sürümü 5.2.11 ve Apache sürümü 1.3.41 kısıtlamaları verilen iyi bir yol biliyor mu?

2 Cevap

Ne yazık ki, ModPHP + Apache altında çalışan PHP pcntl_ * kullanımı () işlevlerini izin vermez olmadığını görünüyor. Linux üzerinde çalışan ve ne zaman, PHP'nin kendisi bir senaryo üzerinde zaman aşımı ayarı sağlar tesisleri sadece komut kendisi harcanan zaman için geçerli, not zaman engellenen bir DB sorgu için bekleyen geçirdi.

Bu nedenle, yeni bir süreç başlatma genel stratejisine must resort ardından ana süreç poll bağlantısı olan, "engelleyebilir şeyler yapmak" için (biz) (pcntl_fork arayamam) ve pes N saniye sonra. Bunu yapmanın bir yolu ve bir stream_select zaman belirli bir süre sonra durur () yoklama döngü (stream_set_blocking () üzerinden) engellenmeyen ayarlanmış PHP-yan borularda) (proc_open ile.

Bu çeşitli düzeylerde can sıkıcı bir durum. Öncelikle, düzgün çocuk sürecini başlatmak için emin olun ve güvenle çeşitli çocuk başarısızlık koşulları ile düzgün emin yoklama mantık fırsatlar yapmak zorunda, sonra ebeveynden çocuğa gerekli işlemi hakkında bilgi aktarmak için var, o zaman güvenli bir şekilde geçmek zorunda geri çocuktan ebeveyne bilgi, ve nihayet (ana süreç birçok yineleme üzerinde devam ederse önemli hale geldiği) daha sonra düzgün her şeyi temizlemek gerekir. Burada karmaşıklığı ben ilk defa öyle hemen hemen herkes davranış gerçekten sağlam önce hata tespit hafta geçirmek zorunda olacak bahse girerim böyle olduğunu. Eğer açık oylama frekans üzerinde kontrol ve hata işlemeyi olmasına rağmen Ve, aynı zamanda yeni bir süreç başlatılması ile ilgili maliyetleri var.

Ben bu tür all sorunlarına hayır "tek beden herkese uyar" çözüm yoktur hibe, ama everyone kim bir Oracle veritabanına konuşmak zorunda PHP bir web uygulaması yazmış var bir kez ya da başka "sorgu X çalıştırmak ve biz geri N saniye içinde bir cevap alamadım bir Exception atmak" istedi. Yani everyone kim must Yukarıda anlatılan bütün sistemi uygulamak (veya bunu zaten yapmış başka birini bulmak), bu davranışı istediğini bana saçma vurur.

Ben bu durum için ben doğrudan sorgu zaman aşımı kontrol etmeye düşünüyorum. Bunu yapmak için en iyi yolu, daha sonra mysqli::options fonksiyonuna erişim çünkü, yerine MySQL modülünden daha PHP'nin MySQLi modülünü kullanmak olacaktır.

Mysqli :: seçeneklerini kullanarak, size bir bağlantı başına temelinde istediğiniz ne olursa olsun sorgu zaman aşımı değerini ayarlayabilirsiniz. Çıkış o zamanlar sonra, kısa sürede olduğu gibi, normal akışının bir parçası olarak kodunuzda hata kontrol edebilirsiniz.

Size (ya da MySQL 5 değil istimal) MySQLi kullanamıyorsanız, her zaman MySQL seçenekleri doğrudan bu değeri ayarlayabilirsiniz, ama tabii bu uygulama üzerinde daha büyük bir etkiye sahip olacaktır.

Edit

Yorumlarınız yanıt olarak, ben bu muhtemelen işe yaramayacak görebilirsiniz. Burada sadece aksak düşündüm bir şey, ama sizi alabilirsiniz.

set_time_limit() function bir PHP komut dosyası yürütme üzerinde genel bir zaman sınırı koyabilirsiniz, ve bu sınır aşıldığı takdirde, bir PHP Ölümcül Hata tetiklenir. Onu aramak Ancak, zamanlayıcı ... sıfıra sıfırlar ve PHP Önemli Hatalar ele alınabilir.

Kendi hata işleme fonksiyonu yazmak, ve sorun sorguyu yürütmek hemen önce, set_error_handler() aracılığıyla kullanıma içine takas olabilir. Hemen set_time_limit() arama ve sorguyu çalıştırın. Zaman sınırı aşıldı alırsa, bir ölümcül hata tetikleyebilir, ve hata işleme fonksiyonu gidecek. Oradan onunla devam edebilirsiniz.

Bunu tetikleyen almazsa, doğru sorgudan sonra set_time_limit() başka bir çağrı ile sayacını sıfırlamak, ve sonra restore_error_handler() yerine geri varsayılan hata işleme işlevini takas için kullanabilirsiniz.

Ben aksak, dedi, ama belki de işe yarayabilir gibi?