Eşzamanlılık Sorunu

2 Cevap php

Ben MySQL ve PHP + Propel 1.3 kullanırken bir eşzamanlılık sorun gibi görünüyor ne yaşıyorum. Aşağıda Propel nesne "kaydetmek" yöntemi küçük bir örneğidir.

public function save(PropelPDO $con = null) {
    $con = Propel::getConnection();
    try {
        $con->beginTransaction();
        sleep(3); // ignore this, used for testing only
        parent::save($con);
        $foo = $this->getFoo(); // Propel object, triggers a SELECT

        // stuff is happening here...

        $foo->save($con);
        $con->commit();
    } catch (Exception $e) {
        $con->rollBack();
        throw $e;
    }
}

Sorun $ foo nesnedir. En çok kısa bir süre içinde başka sonra örnek yöntemi birinin iki çağrı olsun diyelim. Bazı durumlarda, ikinci işlem $ fan okur ...

$foo = $this->getFoo();

Ilk işlem kaydetmek için şans olmuştur ... önce ...

$foo->save($con);

... İkinci işlem tarafından okunan $ foo modası geçmiş olacak ve kötü şeyler olur.

Nasıl tablo kilitleme böylece daha sonraki işlemler sadece ilk işini bitirdikten sonra ondan okuyabilir Foo nesneler saklanır zorlayabilir?

EDIT: bağlam bir web uygulaması. Kısacası, bazı durumlarda I (getiriliyor ve $ foo tasarrufu arasında olur) bazı veri değişikliği yapmak için ilk isteği istiyorum. Tüm sonraki istekler değişiklik yapmak mümkün olmamalıdır. Değişiklik meydana gelecektir olsun ya da zorlama $ foo devlet (tablo satır özniteliği) bağlıdır. İki işlemler aynı $ foo almak durumunda değişiklik iki kez soruna neden olan oluşacaktır.

2 Cevap

Eğer ekran / uygulama bu varolan satır yüklediğinizde, LastChgDate de yükleyin. zaman kaydetmek, kullanmak "VE LastChgDate = thevalue". sıfır ise, "başkası zaten bu rekor kaydetmiştir" bir hata döndürür ve geri alma ve diğer değişiklikler, güncelleştirmenin etkilenen satır sayısını kontrol edin. Bu mantık ile yerde sadece bir satır kaydedebilirsiniz bunu yüklendiğinde gibi aynı eğer. yeni çünkü yeni satırlar için, INSERT, bu gerekli değildir.

MySQL, ben kilidi gerçekleştirmek için UPDATE SELECT kullanabilirsiniz düşünüyorum.

Başka bir seçenek GET_LOCK kullanmaktır ve RELEASE_LOCK MySQL işlevi kaynağa erişimi kontrol etmek için kullanabilirsiniz adlı kilitleri yaratmak için çağırır.

Bu yaklaşımların bazı olumsuzlukları vardır. Ben çok onları kendim kullanmadım ve onlar MySQL özeldir ama onlar sizin için işe yarayabilir.