İyimser kilitleme neden kötümser kilitlemeden daha hızlıdır?


9

Her iki kilitleme şekli de bir işlemin o anda başka bir işlem tarafından kullanılıyorsa kaydın doğru bir kopyasını beklemesine neden olur. Kötümser kilitleme ile, kilit mekanizması DB'nin kendisinden (yerel bir kilit nesnesi) gelirken, iyimser kilitleme ile kilit mekanizması, bir kaydın "bayat" olup olmadığını kontrol etmek için bir zaman damgası gibi bir satır sürüm oluşturma biçimidir.

Ancak her ikisi de 2. sürecin askıda kalmasına neden oluyor. Öyleyse soruyorum: iyimser kilitlemenin neden kötümser kilitlemeden daha hızlı / üstün olduğu düşünülüyor? Ve kötümserliğin iyimserliğe tercih edildiği kullanım durumları var mı? Şimdiden teşekkürler!


5
Adlandırmada çok kısa bir açıklama var. İyimser kilitleme, çakışan kilitlenme şansı düşük olduğunda iyi çalışır. Birden fazla sürecin etkileşimi konusunda iyimseriz. Kötümser kilitleme şansı yüksek olduğunda kötümser kilitleme iyi çalışır. Birden fazla sürecin etkileşimi konusunda kötümseriz. Her ikisi de karşıtlarının daha uygun olduğu yerlerde en iyi şekilde performans gösterecektir.
Mark Storey-Smith

iyimser kilitleme, iş yükünüze bağlı olarak kötümser kilitlemeden daha hızlı olabilir veya olmayabilir.
AK

Yanıtlar:


8

Şu sorudan yinelenen soru:

/programming/129329/optimistic-vs-pessimistic-locking

Yukarıdaki bağlantıdan yanıtı Kopyala / Yapıştır:

İyimser Kilitleme, bir kaydı okuduğunuz, sürüm numarasını not ettiğiniz ve kaydı geri yazmadan önce sürümün değişip değişmediğini kontrol ettiğiniz bir stratejidir. Kaydı geri yazdığınızda, güncellemenin atomik olduğundan emin olmak için sürüme filtre uygularsınız. (örneğin, sürümü kontrol edip kaydı diske yazdığınızda arasında güncellenmedi) ve sürümü tek bir tıklamayla güncelleyin.

Kayıt kirliyse (yani sizinkinden farklı bir sürüm) işlemi iptal edersiniz ve kullanıcı kaydı yeniden başlatabilir.

Bu strateji en çok oturumunuz için veritabanıyla bağlantı kurmanız gerekmeyen yüksek hacimli sistemler ve üç katmanlı mimariler için geçerlidir. Bu durumda, bağlantılar bir havuzdan alındığından istemci aslında veritabanı kilitlerini koruyamaz ve bir bağlantıdan diğerine aynı bağlantıyı kullanmıyor olabilirsiniz.

Kötümser Kilitleme, kaydı bitirene kadar özel kullanımınız için kilitlediğiniz zamandır. İyimser kilitlemeden çok daha iyi bir bütünlüğe sahiptir, ancak Deadlock'lardan kaçınmak için uygulama tasarımınıza dikkat etmenizi gerektirir. Kötümser kilitlemeyi kullanmak için veritabanına doğrudan bir bağlantıya (tipik olarak iki katmanlı bir istemci sunucu uygulamasında olduğu gibi) veya bağlantıdan bağımsız olarak kullanılabilen harici olarak kullanılabilen bir işlem kimliğine ihtiyacınız vardır.

İkinci durumda, işlemi TxID ile açar ve ardından bu kimliği kullanarak yeniden bağlanırsınız. DBMS kilitleri korur ve oturumu TxID üzerinden yedeklemenizi sağlar. İki aşamalı kesinleştirme protokollerini (XA veya COM + İşlemleri gibi) kullanarak dağıtılmış işlemler bu şekilde çalışır.

Düzenle (Performans sorusunu ele almak için daha fazla bilgi ekleme):

Performans akıllıca ortamınıza bağlıdır. Karar vermek için aşağıdaki faktörleri alın:

çoğu durumda eşzamanlılık nedeniyle iyimser olacaksınız. RDBMS ve ortama bağlı olarak, bu daha az veya daha fazla performans gösterebilir. Genellikle İyimser kilitleme ile değerin bir yerde satır sürümünün olması gerektiğini görürsünüz.

Örneğin MS SQL Server ile TempDB'ye taşınır ve sütunun sonuna 12-14 bayt arasında bir şey eklenir. Anlık Görüntü Yalıtımı gibi bir yalıtım düzeyiyle iyimser kilitlemeyi açmak parçalanmaya neden olabilir ve satırların artık sonunda bir sayfanın dolmasına neden olabilecek ek verilere sahip olması nedeniyle dolgu faktörünüzün ayarlanması gerekecektir. performansınız. TempDB'niz optimize edilmişse, bu o kadar hızlı olmayacaktır.

Sanırım bir kontrol listesi:

  • Satır sürüm oluşturma biçimini işlemek için yeterli G / Ç kaynağınız var mı? Değilse, ek yük eklersiniz. Öyleyse, verileri sık sık yazarken kilitlerken sık sık okuyorsanız, okuma ve yazma arasındaki eşzamanlılıkta iyi bir iyileşme göreceksiniz (yazmalar hala yazmaları engellemesine rağmen, okumalar artık yazmaları engellemeyecektir)
  • -Kodunuz kilitlenmelere karşı hassas mı yoksa kilitleme sorunu yaşıyor musunuz? Uzun kilitler veya çok fazla kilitlenme yaşamıyorsanız, İyimser kilitlemenin ek yükü, işleri daha hızlı yapmaz, elbette, çoğu durumda burada milisaniye konuşuyoruz.
  • - DB'niz büyükse (veya çok sınırlı bir donanımda) ve RDBMS'ye bağlı olarak veri sayfalarınız dolmak üzereyse, büyük sayfa bölünmelerine ve veri parçalanmasına neden olabilir, bu nedenle açtıktan sonra yeniden dizine eklemeyi unutmayın.

Bunlar benim konu hakkındaki düşüncelerim, topluluktan daha çok şey duymaya açık.


Teşekkürler @Ali Razeghi (+1) - Bence dba.se bu soru için daha uygun bir yer. Ayrıca, bu mükemmel bir cevap olmasına rağmen, performans sorunumu cevaplamıyor (biri diğerinden daha hızlı olduğunda). Tekrar teşekkürler!
Mara

Merhaba Mara, bu iyi bir nokta. Cevabı genişlettim. Teşekkürler.
Ali Razeghi

11

İyimser kilitlemeyi yanlış anlıyorsunuz.

İyimser kilitleme, işlemlerin birbirini beklemesine neden olmaz.

İyimser kilitleme muhtemelen bir işlemin başarısız olmasına neden olur, ancak bunu herhangi bir "kilit" alınmadan yapar. İşlem iyimser kilitleme nedeniyle başarısız olursa, kullanıcının baştan başlaması gerekir. "İyimser" kelimesi, tam da bu nedenle işlemlerin başarısız olmasına neden olan koşulun sadece çok istisnai bir şekilde gerçekleşeceği beklentisinden kaynaklanmaktadır. "İyimser" kilitleme yaklaşımı, "Gerçek kilitleri almayacağım çünkü umarım yine de ihtiyaç duyulmayacaklarını umuyorum. Eğer bu konuda yanılmışım, kaçınılmaz başarısızlığı kabul edeceğim."


1

İyimser kilitleme genellikle daha hızlıdır çünkü veritabanı açısından hiçbir kilitleme yoktur. Sürüm sütununa (veya ora_rowscn gibi sözde sütuna) saygı gösterip vermemek tamamen uygulamaya bağlıdır. Normalde aynı veritabanına bağlı birçok uygulamanız vardır, bu nedenle db paylaşılan kaynak olur ve asılı kalırsa tüm istemciler etkilenir.

İyimser kilitleme stratejisiyle, müşteri tarafında 'asılı' olur ve diğerlerini etkilemez.

Bununla birlikte, bir kayıt sık sık güncellenirse, çok sayıda kez tekrar okuyabilirsiniz (iyimser kilitleme durumunda), böylece iyimser stratejinin en faydalarını yenebilirsiniz.

Her iki yaklaşımın da üstünlüğü konusunda anlaşamadım; her ikisi de yanlış kullanılabilir. Kötümser, sadece daha tehlikeli olduğu için hataya daha yatkındır: kilitleme db seviyesinde gerçekleşir, RDMS'ye bağlıdır, neyin kilitlendiğini kontrol edemeyebilirsiniz (kilit yükseltme), kilitleme sırasını manuel olarak ele almanız gerekir.


ilginç nokta a1ex07, iyimser kilitleme yine de kilitleme içerir, çünkü yazma her zaman diğer yazma engeller, değil mi?
Ali Razeghi

Hayır değil. Bu yüzden "daha hızlı".
Erwin Smout

Oracle için geçerli olabilir, ancak MS SQL Server için varsayılan olarak 'okuma işlenmiş' yalıtım düzeyini kullandığından, iyimser kilitleme okuyucuların ve yazar iş parçacıklarının aynı anda çalışmasına izin verecektir, ancak yazma işlemleri engelleme iş parçacığı başlayana kadar yazmaları engelleyecektir.
Ali Razeghi

@Ali Razeghi: Demek istediğini takip ettiğimden emin değilim. `` READ_COMMITTED_SNAPSHOT` açık değilse SQLServer'da okunan yazarlara sahip okuyucular varsayılan olarak engellenir. İyimser kilitleme, db kaynağında (satır / sayfa / tablo) bir kilit değil, sürüm beklenen ile eşleşmiyorsa kaydı güncellememek için veritabanı kullanan tüm uygulamalar arasında bir tür anlaşmadır.
a1ex07

1
@Eamon Nerbonne: 'Yazarlar okuyucuları engellemiyor' dedim ... "Yazarları engelliyor / yazarları engellemiyor" hakkında bir şeyden bahsettiğim yeri nereden gördünüz?
a1ex07

0

İyimser kilitleme, eşzamanlı işlemlerin birbirini etkilemeden tamamlanabileceğini varsayar. Dolayısıyla iyimser kilitleme daha hızlıdır çünkü işlem yaparken hiçbir kilit uygulanmaz. Tedavi etmeyen eşzamanlılık sorunlarına yol açmaması önlenir. İşlem sadece başka hiçbir işlemin verileri değiştirmediğini doğrular (Veri Kümeleri, Zaman Damgası Veri türü, Eski ve yeni değeri kontrol et). Değişiklik durumunda işlem geri alınır.

Kötümser kilitleme, eşzamanlı işlemlerin birbiriyle çakışacağını varsayar, bu yüzden kilit gerektirir, işlem yönetiminin İZOLASYON düzeyini (Okunmadı, Okundu Taahhütlü, Tekrarlanabilir Okuma ve Diziselleştirilebilir) belirterek yapılır. kilitler paylaşılan kaynakları veya nesneleri korumaya yarar (Tablolar, Veri Satırları, Veri Blokları, Önbellek Öğeleri, Bağlantılar ve Tüm Sistemler). Paylaşılan kilitler, güncelleme kilidi, iç kilit, özel kilitler, işlem kilitleri, DML kilitleri, şema kilitleri ve yedekleme kurtarma kilitleri gibi birçok kilit türümüz vardır.

daha fazla fikir edinmek


-3

Kötümser kilitlemenin iyimser olmaktan ziyade yavaş olduğunu veya iyimserliğin daha hızlı olduğunu söylemek yanlıştır. Bu uygunsuz düşünme biçimini göstermek için klasik bir sorgu, farklı RDBMS'de bir araya gelmektir:

SELECT COUNT(*) FROM atable

Doğal olarak iyimser yaklaşımı destekleyen RDBMS'de, bu sorgunun zamanının, doğal olarak kötümser bir kilidi olanlardan çok daha önemli olduğunu göreceksiniz.

Örneğin, bilgisayarımda aynı sorgu SQL Server'da 27 ms ve PostGreSQL'de 109 alır ...

MVCC satırlarının ölü sürümlerini okumak için gereken ek yük ve toplamda hayalet kayıtlarını saymamak kötümser olmayan ekstra bir maliyet getirir!


4
DBMS eşzamanlılık kontrolü yaklaşımı iyimser / kötümser kilitleme ile dikeydir ve iki farklı DBMS'de sorgu çalışma sürelerini karşılaştırmak yanıltıcıdır.
mustaccio

SQL Server iki kilitleme modunu yapabildiğinden, bir kullanıcı eşzamanlılık yaklaşımında gerçek bir işaret yaparak bunu kolayca karşılaştırabilirsiniz.
user7370003
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.