Bunun gibi tek bir ifade MyISAM veya InnoDB ile, bir işlemle veya autocommit = ON ile aynı şekilde çalışır. Sorguyu yapacak kadar engeller, böylece diğer bağlantıyı engeller. Tamamlandığında, diğer bağlantı devam eder. Her durumda, sütun yakında 11 azaltılır.
Üçüncü bir kullanıcı, 0 veya 4 veya 7 veya 11 oranında azaltılmış değeri görebilir. "Çok kesin zaman" gerçekten mümkün değildir, çünkü her ifadenin yürütülmesinin bir noktasında tek dişli bir kilit kontrol edilir / ayarlanır / . Yani onlar, olup edecektir Çok hızlı onu göremiyorum, serileştirilebilir.
InnoDB tabloları değil, yalnızca satırları kilitler. (Tamam, DDL deyimi daha kalın kilitler yapar.)
Daha ilginç olan şey, iki şeyi değiştiren veya fark edilir bir zaman alan bir işlemdir:
Niyet Olgu: Tek ürün ancak zaman alıyor:
BEGIN;
SELECT something;
think about it for a while
UPDATE that something;
COMMIT;
Seçimin şu şekilde yazılması gerekir:
SELECT something FOR UPDATE;
Bu, diğer satırlara "Satırı güncellemeyi planlıyorum; lütfen bana bulaşma" der. (Bu örneği gündeme getiriyorum, çünkü pek çok yeni kişi bu inceliği kaçırıyor.)
Kilitlenme durumu: 2 şeyle uğraşmak:
BEGIN; -- in one connection
UPDATE thing_1;
UPDATE thing_2;
COMMIT;
BEGIN; -- in another connection, at the "exact same time"
UPDATE thing_2;
UPDATE thing_1;
COMMIT;
Bu bir kilitlenmenin klasik örneğidir - her biri bir şey alır ve sonra başka bir şeye ulaşır. Açıkçası işe yaramaz. Bir işlem öldürüldü; diğeri tamamlanır. Bu nedenle, hataları kontrol etmeniz gerekir , böylece keşfedebilirsiniz.
Bir kilitlenmeye karşı normal tepki, başarısız olan tüm işlemi yeniden oynatmaktır. O zamana kadar, diğer bağlantı karışmayacak ve sorunsuz bir şekilde ilerlemeli. (Tamam, ancak başka bir bağlantı başka bir kilitlenme oluşturabilir.)
Gecikme Durumu: İki bağlantı aynı sırayla birden çok şeyi tutarsa, diğeri bitene kadar gecikebilir. Bunu "sonsuza kadar beklemekten" kaçınmak için varsayılan 50 saniyedir innodb_lock_wait_timeout
. Basit UPDATEs
çiftiniz aslında bu duruma bir örnektir. Biri hemen bitecek; diğeri ilk bitene kadar durdu.
Bir Kilitlenmenin (bazı durumlarda) dokunduğunuz şeyleri tutarlı bir şekilde sipariş ederek nasıl bir Gecikmeye dönüştürülebileceğini unutmayın.
autocommit = 1: Bu ayar ile ve çağrı yapmadan BEGIN
, her ifade etkili bir şekilde:
BEGIN;
your statement
COMMIT;
autocommit = 0: Bu, gerçekleşmesini beklerken sorun. Bir yazma sorgusu gerçekleştirdiğinizde, a BEGIN
dolaylı olarak oluşturulur. Ancak, nihayetinde vermek sizin sorumluluğunuzdadır COMMIT
. Bunu yapmazsanız, sisteminizin neden asıldığını merak edeceksiniz. (Bir başka yaygın yeni hata.) Tavsiyem: "Asla kullanma =0
".