SORU
19 Kasım 2010, Cuma


mySQL İşlemleri vs Kilitleme Tabloları

Biraz vs tabloları veritabanı bütünlüğünü sağlamak ve emin SEÇİN ve bir GÜNCELLEME yapmak için kilitleme senkronize kalır hareketleri ile kafam karıştı ve başka bir bağlantı uğratır. İhtiyacım var:

SELECT * FROM table WHERE (...) LIMIT 1

if (condition passes) {
   // Update row I got from the select 
   UPDATE table SET column = "value" WHERE (...)

   ... other logic (including INSERT some data) ...
}

Başka sorgular ve SELECT aynı (okuma 'eski değer' bağlantı satır güncelleştirme tamamlanmadan önce müdahale yapacak emin olmak istiyorum

LOCK TABLES table sadece işim bittiğinde sadece 1 bağlantı bir anda bunu yapıyor emin olun, ve kilidini açmak için varsayılan biliyorum, ama bu overkill gibi görünüyor. Bir işlem içinde kaydırma aynı şeyi (başka bir bağlantı başka bir hala işlerken aynı işlemi girişimleri sağlama) yapmak istiyorsunuz? Veya SELECT ... FOR UPDATE SELECT ... LOCK IN SHARE MODE Bir daha mı iyi olur?

CEVAP
19 Kasım 2010, Cuma


Kilitleme tabloları kilitledin tablo/satır etkileyen diğer DB engeller. Ama kilitler, ve kendilerini, mantığınız tutarlı bir durumda çıkar sağlamak DEĞİL.

Bir bankacılık sistemi düşünün. Fatura online ödeme yaparken, en az iki hesap işlem tarafından etkilenen var: hangi para alınır hesabınız. Ve içine para transfer hesapları,. Ve mutlu bir şekilde tüm hizmet ücretleri mevduat alacaklar banka hesap işlem ücret. Bankalar derecede aptal olduğu göz önüne alındığında bugünlerde herkesin bildiği gibi, diyelim, sistem böyle çalışıyor dediler

$balance = "GET BALANCE FROM your ACCOUNT";
if ($balance < $amount_being_paid) {
    charge_huge_overdraft_fees();
}
$balance = $balance - $amount_being paid;
UPDATE your ACCOUNT SET BALANCE = $balance;

$balance = "GET BALANCE FROM receiver ACCOUNT"
charge_insane_transaction_fee();
$balance = $balance   $amount_being_paid
UPDATE receiver ACCOUNT SET BALANCE = $balance

Şimdi, kilit yok ve hiç bir işlem ile, bu sistemin en büyük birden fazla ödeme hesabı üzerinde gerçekleştirilen çeşitli yarış koşulları, açıktır, ya da alıcının paralel hesap. Kodunuzu bakiyesi alınan ve huge_overdraft_fees yaparken (), ıvır zıvır, diğer ödeme kodu paralel olarak aynı tür olması mümkün. Olacaklar almak dengesi ($100), işlemleri (al 20 dolar ödüyorsunuz, ve 30 dolar veriyorlar vidalama ile), ve şimdi her iki kod yollara sahip iki farklı dengeler: $80 $70. Bağlı olarak hangileri bitirir son, sonun da bu iki dengelerin hesabınız yerine $50 olmalıydın sona erdi ($100 - $20 - $30). Bu durumda, "sizin lehinize banka hatası".

Şimdi gelelim kilit kullandığını söylüyor. Fatura ödeme ($20) ve hesap kaydı kazanır kilitleri ilk boru vurur. Şimdi özel kullanımı var, ve denge $20 indirim ve yeni bir denge, huzur içinde geri yazabilir... ve hesabını beklendiği gibi 80 dolar ile biter. Ama... - vay vay... Sen gitmeyi dene, güncelleme hesapları, ve kilitli, kilitli ve daha uzun kod sağlar, zaman aşımına uğramadan işlem... ile uğraştığımızı aptal bankalar, bu yüzden yerine uygun hata işleme kodu sadece çeker exit() * * * $20 kayboluyor içine bir puf elektronlar. Şimdi dışardasın $20, ve hala alıcı için 20 dolar borçlu ve telefon repossessed alır.

Yani... hareketleri girin. Bir işlem, hesabınız, banka $20, $20... ve bir şey daha darbeler ile alıcı kredi çalışın başlatın. Ama bu sefer exit() kod sadece rollback, ve puf yerine, $20 sihirli bir şekilde hesabınıza geri eklenir.

Sonuçta, bu aşağı kaynar:

Kilitler ile uğraşıyoruz, herhangi bir veritabanı kayıtları ile müdahale herkesten uzak tutun. İşlemleri "" "yaptığın şey." daha önce müdahale hataları daha sonra herhangi bir Ne yalnız işler yolunda işe garanti edebilir. Ama birlikte yapıyorlar.

yarınki ders: Kilitlenmeleri Sevinç.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Awesomesauce Network

    Awesomesauce

    4 EKİM 2012
  • Branboy3

    Branboy3

    12 AĞUSTOS 2012
  • CrazyMan

    CrazyMan

    14 Mayıs 2008