Neredeyse aynı anda yürütme 2 özdeş sorguları durdurmak?

3 Cevap php

Ben neden bir hata var bir AJAX tabanlı oyun geliştirdik (çok uzak, ama hacim olarak en az saatte bir kez olur) nedense iki istekleri ben izlenir (sonuncusu, neredeyse aynı anda işleme sayfasına gönderilen olsun nerede istekleri) .0001 ms'lik bir fark vardı. Orada sorgu iki kez idam almaz emin olmak için idam hemen önce bir çek, ancak fark çok küçük olduğundan bir sonraki sorgu yürütüldüğünde alır önce, çek bitmiş değil. Ben bu oyunda ciddi sorunlara neden olarak bunu önlemek için nasıl stumped.

Sadece daha temiz olması için, sorgu oyunda yeni bir tur başlıyor, bu yüzden iki kez çalıştırıldığında, bu oyunu tatili aynı anda 2 tur başlar, bu yüzden yürütülmesini senaryoyu durdurmak mümkün gerekiyorsa Önceki yuvarlak olduğunu, önceki yuvarlak 0,0001 ms önce başlamış olsa bile, bitmedi.

3 Cevap

Hüner hem dişleri için başarılı olamaz bir şey yapmak için bir atom güncelleştirme deyimini kullanmaktır. Her ikisi de başarılı olmamalıdır, bu yüzden sadece bir sorgu gibi yapabilirsiniz:

UPDATE gameinfo SET round=round+1 WHERE round=1234

1234 ilerleme oldu geçerli yuvarlak olduğu. Sonra etkilenen satırların sayısını kontrol edin. Iplik sıfır satır etkiler ise, başarısız oldu ve bir başkası elden önce yaptım. Ben autocommit olduğu gibi üzerinde kendi işlem idam olacağını varsayarak yaşıyorum.

Yani gerçekten ihtiyacınız bir uygulama geniş mutex. ) sem_acquire () bunu sağlamak (akın - ama sadece sistem düzeyinde - uygulama mutliple sunucuya yayılır eğer düğümleri koordine kendi soket sunucusu memcached kullanmak ya da uygulamak gerekiyordu.

Alternatif olarak, ortak bir depolama alanı olarak bir veritabanı kullanabilirsiniz - örneğin MySQL bir tablo üzerinde bir kilit elde olan, yuvarlak son başlatılan gerektiğinde güncelleme yeni bir tur söylemek satır başlıyor olmadığını kontrol edin (ve bu hatırlıyorum - o tabloyu kilidini Devam .....

C.

Kilitler, bunu yapmanın bir yolu vardır, ancak bazı durumlarda basit bir yolu isteğiniz idempotent yapmaktır. Bu sadece tekrar tekrar çağırarak kez arayarak tam olarak aynı etkiye sahip olduğu anlamına gelir.

Örneğin, şu anda çağrı etkili bu $round++; Açıkça tekrarlanan çağrılar sorun neden olur yapar.

Ama bunun yerine yapabileceği $round=$newround; İşte tekrarlanan çağrılar herhangi bir etkisi olmaz, yuvarlak önceden ayarlanmış olduğundan ve ikinci çağrı sadece aynı değere ayarlar.