Tablodaki kilitlerle işlem yalıtım düzeyleri ilişkisi


105

Yaklaşık 4 izolasyon seviyesi okudum:

Isolation Level       Dirty Read    Nonrepeatable Read  Phantom Read  
READ UNCOMMITTED      Permitted       Permitted           Permitted
READ COMMITTED              --        Permitted           Permitted
REPEATABLE READ             --             --             Permitted
SERIALIZABLE                --             --              --

Her işlem izolasyonunun masaya getirdiği kilidi anlamak istiyorum

READ UNCOMMITTED - no lock on table
READ COMMITTED - lock on committed data
REPEATABLE READ - lock on block of sql(which is selected by using select query)
SERIALIZABLE - lock on full table(on which Select query is fired)

Aşağıda, işlem izolasyonunda ortaya çıkabilecek üç olay yer almaktadır
Kirli Okuma - Kilit yok
Tekrarlanamaz Okuma - kaydedilen verilerde kilit olarak kirli okuma yok
Fantom Okuma - sql bloğunda kilitlenme (seçme sorgusu kullanılarak seçilir)

Bu izolasyon seviyelerini nerede tanımladığımızı anlamak istiyorum : sadece jdbc / hibernate seviyesinde veya ayrıca DB'de

Not: Oracle'da İzolasyon seviyelerindeki bağlantılardan geçtim , ancak beceriksiz görünüyorlar ve veritabanına özel konuşuyorlar


3
Bu tamamen veritabanına bağlıdır. Farklı veri tabanı, izolasyon seviyeleri için farklı algoritmalar kullanabilir. Bazıları MVCC kullanabilir (belirli sorgularda kilit yok), bazıları katı 2 fazlı kilitleme (paylaşımlı ve özel kilitler) kullanabilir.
brb tea

Yanıtlar:


158

Her işlem izolasyonunun masaya getirdiği kilidi anlamak istiyorum

Örneğin, 3 eşzamanlı işleminiz var A, B ve C. A bir işlemi başlatır, verileri yazar ve tamamlama / geri alma (sonuçlara bağlı olarak). B sadece SELECTverileri okumak için bir ifade yürütür . C verileri okur ve günceller. Tüm bu süreçler aynı T tablosu üzerinde çalışır.

  • HABER VERMEDEN OKUYUN - masanın üzerinde kilit yok. Tablodaki verileri üzerine yazarken okuyabilirsiniz. Bu, A'nın verileri yazdığı (taahhüt edilmemiş) ve B'nin bu taahhüt edilmemiş verileri okuyabileceği ve (herhangi bir amaç için) kullanabileceği anlamına gelir. A bir geri dönüş gerçekleştirirse, B hala verileri okumuş ve kullanmıştır. Fiziksel olarak ilişkili olmayan tablolarda veri boşluklarına yol açabileceğinden bu, verilerle çalışmanın en hızlı ancak en güvensiz yoludur (evet, iki tablo mantıksal olarak olabilir ancak gerçek dünya uygulamalarında fiziksel olarak ilişkili olmayabilir = \).
  • READ COMMITTED - kaydedilen verilere kilitlenin. Sadece kaydedilen verileri okuyabilirsiniz. Bu, A'nın verileri yazdığı ve B'nin A tarafından kaydedilen verileri A bir kaydetme gerçekleştirene kadar okuyamayacağı anlamına gelir. Buradaki sorun, C'nin B ve B istemcisinde okunan ve kullanılan verileri güncelleyebilmesinin güncellenmiş verilere sahip olmamasıdır.
  • TEKRARLANABİLİR OKUMA - bir SQL bloğunu kilitleyin (seçme sorgusu kullanılarak seçilir). Bu, B'nin veriyi bazı koşullar altında okuduğu anlamına gelir WHERE aField > 10 AND aField < 20, yani A, aFielddeğerin 10 ile 20 arasında olduğu yerlerde verileri ekler , ardından B verileri tekrar okur ve farklı bir sonuç alır.
  • SERİLEŞTİRİLEBİLİR - tam bir tabloya kilitlenir (Seçim sorgusunun tetiklendiği). Bu, B'nin verileri okuduğu ve başka hiçbir işlemin tablodaki verileri değiştiremeyeceği anlamına gelir . Bu, verilerle çalışmanın en güvenli ancak en yavaş yoludur. Ayrıca, basit bir okuma işlemi tabloyu kilitlediğinden , bu üretimde ağır sorunlara yol açabilir: T tablosunun bir Fatura tablosu olduğunu, X kullanıcısının günün faturalarını bilmek istediğini ve Y kullanıcısının yeni bir fatura oluşturmak istediğini hayal edin. X faturaların okunmasını gerçekleştirirken, Y yeni bir fatura ekleyemez (ve para söz konusu olduğunda, insanlar, özellikle de patronlar gerçekten sinirlenir).

Bu izolasyon seviyelerini nerede tanımladığımızı anlamak istiyorum : yalnızca JDBC / hazırda bekletme seviyesinde veya ayrıca DB'de

JDBC'yi kullanarak, bunu kullanarak tanımlarsınız Connection#setTransactionIsolation.

Hazırda Bekletme'yi Kullanma:

<property name="hibernate.connection.isolation">2</property>

Nerede

  • 1: HAZIRLANMADI OKUYUN
  • 2: TAMAMLANDI OKUYUN
  • 4: TEKRARLANABİLİR OKUMA
  • 8: SERİLEŞTİRİLEBİLİR

Hazırda bekletme yapılandırması buradan alınır (üzgünüm, İspanyolca dilinde).

Bu arada, izolasyon seviyesini RDBMS'de de ayarlayabilirsiniz:

ve devam ediyor ...


docs.oracle.com/cd/B12037_01/server.101/b10743/consist.htm Sadece Oracle için eklemek için: Bir işlemin başlangıcında şu ifadelerden birini kullanarak bir işlemin izolasyon seviyesini belirleyebilir: TRANSACTION ISOLATION SET DÜZEY OKUMA YAPILDI; İŞLEM İZOLASYON SEVİYESİNİ SERİLEŞTİRİLEBİLİR; İŞLEMİ AYARLA YALNIZCA OKUYUN;
Öğrenci

2
Ayrıca, her işlemin bir SET TRANSACTION ifadesiyle başlamasının ağ oluşturma ve işlem maliyetinden tasarruf etmek için, sonraki tüm işlemler için işlem yalıtım düzeyini ayarlamak üzere ALTER SESSION deyimini kullanabilirsiniz: ALTER SESSION SET ISOLATION SET ISOLATION_LEVEL SERIALIZABLE; ALTER SESSION SET ISOLATION_LEVEL OKUMA BAŞLADI;
Öğrenci

12
TEKRARLANABİLİR OKUMA ile ilgili olarak - Bunu göstermek için daha iyi bir örnek olduğunu düşünüyorum: B bir işlem başlatır, sql bloğunda verileri okur NEREDE aField> 10 VE aField <20, bu veriler işlem bitene kadar kilitlenir. A bu verileri güncellemeye çalışır ancak kilit nedeniyle bekler. Şimdi aynı işlemde B bu veriyi tekrar okuduğunda, aynı veriyi okumak garantilidir, çünkü kilitlidir. Yanlışsam düzelt.
BornToCode

1
@LuiggiMendoza Genel konsept olarak, izolasyon seviyeleri sadece Kirli Okuma , Tekrarlanamayan Okuma ve Hayali Satırlar hakkındadır . Kilitler (S2PL) veya MVCC, farklı satıcılar için uygulamalardır.
brb tea

4
@LuiggiMendoza - Doğru değildim, böyle olmalı - B'nin okuduğu veri değişmez, ancak B tarafından yapılan seçimler daha fazla satır döndürebilir. Bunun nedeni A, B'nin okuduğu satırları A serbest bırakana kadar değiştiremez . Ancak A , where koşulunu nitelendiren yeni satırlar ekleyebilir (ve bu nedenle, bir dahaki sefere A bir seçim gerçekleştirecek, daha fazla satırla farklı bir sonuç alacaktır - bir hayalet okuma).
BornToCode

9

Brb Tea'nin dediği gibi, veritabanı uygulamasına ve kullandıkları algoritmaya bağlıdır: MVCC veya İki Fazlı Kilitleme.

CUBRID (açık kaynak RDBMS) , bu iki algoritmanın fikrini açıklar :

  • İki fazlı kilitleme (2PL)

İlki, T2 işlemi A kaydını değiştirmeye çalıştığında, T1 işleminin A kaydını zaten değiştirdiğini bilir ve T1 işleminin tamamlanmasını bekler çünkü T2 işlemi T1 işleminin tamamlanıp tamamlanmayacağını bilemez. geri. Bu yönteme İki fazlı kilitleme (2PL) denir.

  • Çok sürümlü eşzamanlılık denetimi (MVCC)

Diğeri, T1 ve T2 işlemlerinin her birinin kendi değiştirilmiş versiyonlarına sahip olmasına izin vermektir. T1 işlemi A kaydını 1'den 2'ye değiştirmiş olsa bile, T1 işlemi orijinal değeri 1'i olduğu gibi bırakır ve A kaydının T1 işlem versiyonunun 2 olduğunu yazar. Ardından, aşağıdaki T2 işlemi A kaydını değiştirir 1'den 3'e, 2'den 4'e değil ve A kaydının T2 işlem sürümünün 3 olduğunu yazıyor.

T1 işlemi geri alındığında, T1 işlem sürümü olan 2'nin A kaydına uygulanmaması önemli değildir. Bundan sonra, T2 işlemi taahhüt edilirse, 3, T2 işlem versiyonu, A kaydına uygulanacaktır. T1 işlemi T2 işleminden önce yapılırsa, A kaydı 2'ye ve ardından T2 işleminin gerçekleştirilmesi sırasında 3'e değiştirilir. Nihai veritabanı durumu, diğer işlemler üzerinde herhangi bir etki olmaksızın, her bir işlemi bağımsız olarak yürütme durumuyla aynıdır. Bu nedenle ACID özelliğini karşılar. Bu yönteme Çoklu sürüm eşzamanlılık denetimi (MVCC) denir.

MVCC, bellekte artan ek yük (çünkü aynı verilerin farklı sürümlerini tutması gerektiğinden) ve hesaplama (REPETEABLE_READ düzeyinde) pahasına eşzamanlı değişikliklere izin verir, bu nedenle Hiberate gibi verilerin sürümlerini kontrol etmelidir. Optimistick Locking ile yapar ).

2PL İşlem izolasyon seviyeleri aşağıdakileri kontrol eder :

  • Veriler okunduğunda kilitlerin alınıp alınmadığı ve ne tür kilitlerin talep edildiği.

  • Okuma kilitlerinin ne kadar süreyle tutulacağı.

  • Başka bir işlem tarafından değiştirilen satırları referans alan bir okuma işleminin olup olmadığı:

    • Sıradaki özel kilit serbest kalana kadar engelleyin.

    • İfade veya işlem başladığında var olan satırın kaydedilmiş sürümünü alın.

    • Taahhüt edilmeyen veri değişikliğini okuyun.

Bir işlem yalıtım düzeyinin seçilmesi, veri değişikliklerini korumak için edinilen kilitleri etkilemez. Bir işlem her zaman değiştirdiği herhangi bir veriye özel bir kilit alır ve o işlem için ayarlanan izolasyon düzeyine bakılmaksızın işlem tamamlanana kadar bu kilidi tutar. Okuma işlemleri için, işlem izolasyon seviyeleri öncelikle diğer işlemler tarafından yapılan değişikliklerin etkilerinden koruma seviyesini tanımlar.

Daha düşük bir izolasyon düzeyi, birçok kullanıcının aynı anda verilere erişme yeteneğini artırır, ancak kullanıcıların karşılaşabileceği kirli okumalar veya kayıp güncellemeler gibi eşzamanlılık etkilerinin sayısını artırır .

SQL Server'da kilitler ve izolasyon seviyeleri arasındaki ilişkinin somut örnekleri ( READ_COMMITTED_SNAPSHOT = ON ile READ_COMMITED dışında 2PL kullanın)

  • READ_UNCOMMITED: diğer işlemlerin mevcut işlem tarafından okunan verileri değiştirmesini önlemek için paylaşımlı kilitler yayınlamayın. READ UNCOMMITTED işlemleri, geçerli işlemin değiştirilmiş ancak başka işlemler tarafından taahhüt edilmemiş satırları okumasını engelleyen özel kilitlerle de engellenmez. [...]

  • READ_COMMITED:

    • READ_COMMITTED_SNAPSHOT seçeneği KAPALI olarak ayarlanmışsa (varsayılan): geçerli işlem bir okuma işlemi yürütürken diğer işlemlerin satırları değiştirmesini önlemek için paylaşılan kilitleri kullanır. Paylaşılan kilitler ayrıca, diğer işlem tamamlanana kadar ifadenin diğer işlemler tarafından değiştirilen satırları okumasını engeller. [...] Satır kilitleri, sonraki satır işlenmeden önce kaldırılır. [...]
    • READ_COMMITTED_SNAPSHOT, AÇIK olarak ayarlanmışsa, Veritabanı Motoru, her bir ifadeyi, ifadenin başlangıcında var olan verilerin işlem açısından tutarlı bir anlık görüntüsüyle sunmak için satır sürümlemesini kullanır. Verileri diğer işlemlerle güncellemelerden korumak için kilitler kullanılmaz.
  • REPETEABLE_READ: Paylaşılan kilitler, işlemdeki her bir ifade tarafından okunan tüm verilere yerleştirilir ve işlem tamamlanana kadar tutulur.

  • SERİLEŞTİRİLEBİLİR: Aralık kilitleri, bir işlemde yürütülen her bir ifadenin arama koşullarıyla eşleşen anahtar değerleri aralığına yerleştirilir. [...] Aralık kilitleri işlem tamamlanana kadar tutulur.


5

Kilitler her zaman DB seviyesinde alınır: -

Oracle resmi Dokümanı: - Bir işlem sırasında çakışmaları önlemek için, bir DBMS kilitler, işlem tarafından erişilen verilere başkalarının erişimini engelleyen mekanizmalar kullanır. (Her ifadenin bir işlem olduğu otomatik tamamlama modunda kilitlerin yalnızca bir ifade için tutulduğunu unutmayın.) Bir kilit ayarlandıktan sonra, işlem tamamlanana veya geri alınana kadar yürürlükte kalır. Örneğin, bir DBMS, güncellemeler tamamlanana kadar bir tablonun satırını kilitleyebilir. Bu kilidin etkisi, kullanıcının kirli bir okuma almasını, yani kalıcı hale getirilmeden önce bir değeri okumasını önlemek olacaktır. (Kaydedilmemiş güncellenmiş bir değere erişim kirli okuma olarak kabul edilir çünkü bu değerin önceki değerine geri döndürülmesi mümkündür. Daha sonra geri alınan bir değeri okursanız, geçersiz bir değer okumuş olursunuz. )

Kilitlerin nasıl ayarlandığı, işlemlerin hiç desteklenmemesinden çok katı erişim kurallarını uygulayan destekleyici işlemlere kadar değişebilen işlem izolasyon seviyesi olarak adlandırılan seviyeye göre belirlenir.

İşlem izolasyon düzeyinin bir örneği TRANSACTION_READ_COMMITTED'dir ve bu, işlenene kadar bir değere erişilmesine izin vermez. Başka bir deyişle, işlem yalıtım seviyesi TRANSACTION_READ_COMMITTED olarak ayarlanmışsa, DBMS kirli okumaların oluşmasına izin vermez. Arayüz Bağlantısı, JDBC'de kullanabileceğiniz işlem yalıtım düzeylerini temsil eden beş değer içerir.

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.