Tabloları kilitlemek, diğer DB kullanıcılarının kilitlediğiniz satırları / tabloları etkilemesini engeller. Ancak kilitler kendi içlerinde mantığınızın tutarlı bir durumda ortaya çıkmasını SAĞLAMAZ.
Bir bankacılık sistemi düşünün. Çevrimiçi olarak bir fatura ödediğinizde, işlemden etkilenen en az iki hesap vardır: Paranın çekildiği hesabınız. Ve paranın transfer edildiği alıcının hesabı. Ve işlem için tahsil edilen tüm hizmet ücretlerini mutlu bir şekilde yatıracakları bankanın hesabı. Bankaların olağanüstü derecede aptal olduğu göz önüne alındığında (bugünlerde herkesin bildiği gibi), sistemlerinin şu şekilde çalıştığını varsayalım:
$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
Artık kilit ve işlem olmadan, bu sistem çeşitli yarış koşullarına karşı savunmasızdır; bunlardan en büyüğü, hesabınızda veya alıcının hesabında paralel olarak gerçekleştirilen birden çok ödemedir. Kodunuz bakiyeniz alınmış olsa da, huge_overdraft_fees () ve ne yapmıyor olsa da, başka bir ödemenin aynı tür kodu paralel olarak çalıştırması tamamen mümkündür. Bakiyenizi alacaklar (örneğin, 100 $), işlemlerini yapacaklar (ödediğiniz 20 $ 'ı ve sizi mahvettikleri 30 $' ı çıkaracaklar) ve şimdi her iki kod yolunun iki farklı bakiyesi var: 80 $ ve 70 $. Hangisinin en son bitirdiğine bağlı olarak, hesabınızda bu iki bakiyeden birini elde edersiniz, kazanmanız gereken 50 $ yerine (100 $ - 20 $ - 30 $). Bu durumda, "lehinize banka hatası"
Şimdi, kilit kullandığınızı varsayalım. Fatura ödemeniz (20 $) önce boruyu vurur, böylece kazanır ve hesap kaydınızı kilitler. Artık özel kullanımınız var ve 20 $ 'ı bakiyeden düşebilir ve yeni bakiyeyi huzur içinde yazabilirsiniz ... ve hesabınız beklendiği gibi 80 $ ile biter. Ama ... uhoh ... Alıcının hesabını güncellemeye çalışıyorsun ve o kilitlendi ve kodun izin verdiğinden daha uzun süre kilitlendi, işleminiz zaman aşımına uğradı ... Aptal bankalarla uğraşıyoruz, bu yüzden uygun hata yapmak yerine işlem, kod sadece bir çeker exit()
ve 20 dolarınız bir elektron dalgasına dönüşür. Şimdi 20 doların tükendi ve alıcıya hala 20 dolar borçlusun ve telefonunuz yeniden ele geçirildi.
Yani ... işlemleri girin. Bir işleme başlıyorsunuz, hesabınızdan 20 $ borçlandırıyorsunuz, alıcıya 20 $ yatırmaya çalışıyorsunuz ... ve bir şeyler tekrar patlıyor. Ancak bu sefer, exit()
kod sadece yapabilir rollback
ve puf yerine, 20 dolarınız sihirli bir şekilde hesabınıza geri eklenir.
Sonunda, şuna indirgeniyor:
Kilitler, uğraştığınız herhangi bir veritabanı kaydına başkalarının karışmasını engeller. İşlemler, herhangi bir "sonraki" hatanın yaptığınız "önceki" şeylere müdahale etmesini önler. Hiçbiri sonunda her şeyin yolunda gideceğini garanti edemez. Ama birlikte yaparlar.
yarının dersinde: The Joy of Deadlocks.