Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Şunlar için geçerlidir:SQL Server
Azure SQL Veritabanı
Azure SQL Yönetilen Örneği
Azure Synapse Analytics
Analytics Platform Sistemi (PDW)
Microsoft Fabric'teki SQL veritabanı
Herhangi bir veritabanında, işlemlerin yanlış yönetilmesi genellikle çok sayıda kullanıcısı olan sistemlerde çekişme ve performans sorunlarına yol açar. Verilere erişen kullanıcı sayısı arttıkça, işlemleri verimli bir şekilde kullanan uygulamaların olması önemli hale gelir. Bu kılavuz, Veritabanı Altyapısı'nın her işlemin bütünlüğünü sağlamak için kullandığı kilitleme ve satır sürüm oluşturma mekanizmalarını açıklar ve uygulamaların işlemleri verimli bir şekilde nasıl denetleyebileceği hakkında bilgi sağlar.
Not
İyileştirilmiş kilitleme, 2023'te kullanıma sunulan ve kilit belleğini ve eşzamanlı yazma işlemleri için gereken kilit sayısını önemli ölçüde azaltan bir Veritabanı Altyapısı özelliğidir. Bu makale, en iyi duruma getirilmiş kilitleme ile ve kilitleme olmadan Veritabanı Altyapısı davranışını açıklamak için güncelleştirilir.
- Daha fazla bilgi edinmek ve iyileştirilmiş kilitlemenin nerede kullanılabilir olduğunu öğrenmek için bkz. İyileştirilmiş kilitleme.
- Veritabanınızda iyileştirilmiş kilitlemenin etkinleştirilip etkinleştirilmediğini belirlemek için bkz. İyileştirilmiş kilitleme etkinleştirildi mi?
İyileştirilmiş kilitleme, aşağıdakiler dahil olmak üzere bu makalenin bazı bölümlerinde önemli değişikliklere neden olur:
İşlem temelleri
İşlem, tek bir mantıksal iş birimi olarak gerçekleştirilen bir işlem dizisidir. Mantıksal bir iş birimi, işlem olarak nitelenecek şekilde bölünmezlik, tutarlılık, yalıtım ve dayanıklılık (ACID) özellikleri olarak adlandırılan dört özellik göstermelidir.
Bölünmezlik
İşlem, atomik bir iş birimi olmalıdır; tüm veri değişiklikleri gerçekleştirilir veya hiçbiri gerçekleştirilmez.
Tutarlılık
İşlem tamamlandığında tüm verileri tutarlı bir durumda bırakmalıdır. İlişkisel veritabanında, tüm veri bütünlüğünü korumak için tüm kuralların işlemin değişikliklerine uygulanması gerekir. B ağacı dizinleri veya ikiye kat bağlantılı listeler gibi tüm iç veri yapıları işlemin sonunda doğru olmalıdır.
Not
Belgelerde genellikle dizinlere başvuruda B ağacı terimi kullanılır. Rowstore dizinlerinde Veritabanı Altyapısı bir B+ ağacı uygular. Bu, columnstore dizinleri veya bellek için iyileştirilmiş tablolardaki dizinler için geçerli değildir. Daha fazla bilgi için SQL Server ve Azure SQL dizin mimarisi ve tasarım kılavuzuna bakın.
Yalıtım
Eşzamanlı işlemler tarafından yapılan değişiklikler, diğer eşzamanlı işlemler tarafından yapılan değişikliklerden yalıtılmalıdır. bir işlem, başka bir eşzamanlı işlem tarafından değiştirilmeden önceki durumundaki verileri tanır veya ikinci işlem tamamlandıktan sonra verileri tanır, ancak ara durumu tanımaz. Seriye dönüştürülebilirlik olarak adlandırılır, çünkü başlangıç verilerini yeniden yükleyip bir dizi işlemi tümüyle yeniden yürüterek, özgün işlemlerin gerçekleştirilmesinden sonraki duruma verileri tekrardan getirmek mümkündür.
Dayanıklılık
Bir işlem tamamen dayanıklı hale gelip tamamlandığında, etkileri sistemde kalıcı olarak gerçekleştirilir. Değişiklikler, sistem hatası durumunda bile devam eder. SQL Server 2014 (12.x) ve üzeri gecikmeli dayanıklı işlemleri etkinleştirir. Gecikmeli dayanıklı işlemler, işlem günlüğü kaydı diskte kalıcı hale gelmeden önce kaydedilir. Gecikmeli işlem dayanıklılığı hakkında daha fazla bilgi için İşlem Dayanıklılığını Denetlememakalesine bakın.
Uygulamalar, verilerin mantıksal tutarlılığını zorlayan noktalarda işlemleri başlatmak ve sonlandırmaktan sorumludur. Uygulamanın, verileri kuruluşun iş kurallarına göre tutarlı bir durumda bırakan veri değişiklikleri sırasını tanımlaması gerekir. Uygulama, Veritabanı Altyapısının işlemin bütünlüğünü zorunlu kabilmesi için bu değişiklikleri tek bir işlemde gerçekleştirir.
Her işlemin bütünlüğünü sağlayan mekanizmalar sağlamak Veritabanı Altyapısı örneği gibi bir kurumsal veritabanı sisteminin sorumluluğundadır. Veritabanı Altyapısı aşağıdakileri sağlar:
İşlem yalıtımını koruyan kilit mekanizmaları.
İşlem dayanıklılığını sağlamak için kayıt mekanizmaları. Tamamen dayanıklı işlemler için günlük kaydı, işlemler onaylanmadan önce diske kaydedilir. Bu nedenle, sunucu donanımı, işletim sistemi veya Veritabanı Altyapısı örneği başarısız olsa bile, örnek, tamamlanmamış işlemleri sistem hatası noktasına otomatik olarak geri almak için yeniden başlatıldıktan sonra işlem günlüklerini kullanır. Gecikmeli dayanıklı işlemler, işlem günlüğü kaydı diske sağlamlaştırılamadan önce işler. Günlük kaydı diske sağlamlaştırılmadan önce bir sistem hatası olduğunda bu tür işlemler kaybolabilir. Gecikmeli işlem dayanıklılığı hakkında daha fazla bilgi için İşlem Dayanıklılığını Denetlememakalesine bakın.
İşlem bölünmezliğini ve tutarlılığını zorlayan işlem yönetimi özellikleri. İşlem başlatıldıktan sonra işlemin başarıyla tamamlanması (işlenmesi) gerekir veya Veritabanı Altyapısı işlem başladıktan sonra işlem tarafından yapılan tüm veri değişikliklerini geri alır. Bu işlem, verileri bu değişikliklerden önceki durumuna döndürdüğünden işlemi geri almak olarak adlandırılır.
İşlemleri denetleme
Uygulamalar genellikle bir işlemin ne zaman başlayıp ne zaman biteceğini belirterek işlemleri denetler. Bu, Transact-SQL deyimleri veya veritabanı uygulama programlama arabirimi (API) işlevleri kullanılarak belirtilebilir. Sistemin bir işlemi tamamlanmadan önce sonlandıran hataları da doğru şekilde işleyebilmesi gerekir. Daha fazla bilgi için bkz. transactions, Performing Transactions in ODBCve Transactions in SQL Server Native Client.
Varsayılan olarak, işlemler bağlantı düzeyinde yönetilir. Bir bağlantıda bir işlem başlatıldığında, bu bağlantıda yürütülen tüm Transact-SQL deyimleri, işlem bitene kadar işlemin bir parçasıdır. Ancak, birden fazla aktif sonuç kümesi (MARS) oturumunda, Transact-SQL açık veya örtük bir işlem, parti düzeyinde yönetilen ve parti kapsamında olan bir işlem haline gelir. Toplu işlem tamamlandığında, toplu işlem kapsamındaki işlem ya onaylanmaz ya da geri alınmazsa, Veritabanı Motoru tarafından otomatik olarak geri alınır. Daha fazla bilgi için bkz. Birden Çok Etkin Sonuç Kümesi (MARS) kullanma.
İşlemleri başlatma
API işlevlerini ve Transact-SQL deyimlerini kullanarak işlemleri açık, otomatik komut veya örtük işlemler olarak başlatabilirsiniz.
Açık işlemler
Açık bir işlem, bir API işlevi aracılığıyla veya Transact-SQL BEGIN TRANSACTION
, COMMIT TRANSACTION
, COMMIT WORK
, ROLLBACK TRANSACTION
veya ROLLBACK WORK
Transact-SQL deyimlerini vererek işlemin hem başlangıç hem de bitişini açıkça tanımladığınız işlemdir. İşlem sona erdiğinde, bağlantı açık işlem başlatılmadan önce içinde bulunduğu işlem moduna döner ve bu örtük veya otomatik komut modu olabilir.
Aşağıdaki deyimler dışında tüm Transact-SQL deyimlerini açık bir işlemde kullanabilirsiniz:
CREATE DATABASE
ALTER DATABASE
DROP DATABASE
CREATE FULLTEXT CATALOG
ALTER FULLTEXT CATALOG
DROP FULLTEXT CATALOG
DROP FULLTEXT INDEX
ALTER FULLTEXT INDEX
CREATE FULLTEXT INDEX
BACKUP
RESTORE
RECONFIGURE
- Tam metin sistem saklı yordamları
- Veritabanı seçeneklerini veya açık veya örtük işlemler içindeki
sp_dboption
veritabanını değiştiren herhangi bir sistem yordamını ayarlamak içinmaster
.
Not
UPDATE STATISTICS
açık bir işlem içinde kullanılabilir. Ancak, UPDATE STATISTICS
kapsayan işlemden bağımsız olarak işlem tamamlar ve geri alınması mümkün değildir.
Otomatik Onaylama İşlemleri
Otomatik komut modu, Veritabanı Altyapısı'nın varsayılan işlem yönetimi modudur. Her Transact-SQL deyimi tamamlandığında onaylanır veya geri alınır. Bir ifade başarıyla tamamlanırsa taahhüt edilir; herhangi bir hatayla karşılaşırsa geri alınır. Veritabanı Altyapısı örneğine yönelik bir bağlantı, bu varsayılan mod açık veya örtük işlemler tarafından geçersiz kılınmadığından otomatik komut modunda çalışır. Otomatik komut modu aynı zamanda SqlClient, ADO, OLE DB ve ODBC için de varsayılan moddur.
Örtük İşlemler
Bir bağlantı örtük işlem modunda çalışırken, Veritabanı Altyapısı örneği geçerli işlem işlendikten veya geri alındıktan sonra otomatik olarak yeni bir işlem başlatır. Bir işlemin başlangıcını belirlemek için hiçbir şey yapmazsınız; yalnızca her işlemi gerçekleştirir veya geri alırsınız. Örtük işlem modu sürekli bir işlem zinciri oluşturur. Bir API işlevi veya Transact-SQL SET IMPLICIT_TRANSACTIONS ON
deyimi aracılığıyla örtük işlem modunu açık olarak ayarlayın. Bu mod Otomatik İşlem kapanışı olarak da bilinir, bkz. setAutoCommit Metodu (SQLServerConnection).
Bir bağlantı için örtük işlem modu etkinleştirildikten sonra, Veritabanı Altyapısı örneği aşağıdaki deyimlerden herhangi birini ilk yürütürken otomatik olarak bir işlem başlatır:
ALTER TABLE
CREATE
DELETE
DENY
DROP
FETCH
GRANT
INSERT
OPEN
REVOKE
SELECT
TRUNCATE
UPDATE
Yığın Kapsamlı İşlemler
Yalnızca birden çok etkin sonuç kümesi (MARS) için geçerlidir, MARS oturumu altında başlatılan Transact-SQL açık veya örtük bir işlem, bir toplu iş kapsamlı işlem olur. Toplu iş tamamlandığında onaylanmayan veya geri alınmayan bir toplu işlem, Veritabanı Altyapısı tarafından otomatik olarak geri alınır.
Dağıtılmış işlemler
Dağıtılmış işlemler, kaynak yöneticileri olarak bilinen iki veya daha fazla sunucuya yayılır. İşlemin yönetimi, işlem yöneticisi adı verilen bir sunucu bileşeni tarafından kaynak yöneticileri arasında koordine edilmelidir. Veritabanı Altyapısı'nın her örneği, Microsoft Dağıtılmış İşlem Düzenleyicisi (MS DTC) gibi işlem yöneticileri veya dağıtılmış işlem işleme için Açık Grup XA belirtimini destekleyen diğer işlem yöneticileri tarafından koordine edilen dağıtılmış işlemlerde kaynak yöneticisi olarak çalışabilir. Daha fazla bilgi için MS DTC belgelerine bakın.
Veritabanı Altyapısı'nın iki veya daha fazla veritabanına yayılan tek bir örneği içindeki bir işlem dağıtılmış bir işlemdir. Örnek, dağıtılmış işlemi dahili olarak yönetir; kullanıcıya, yerel bir işlem olarak çalışır.
Uygulamada, dağıtılmış bir işlem yerel işlemle çok aynı şekilde yönetilir. İşlemin sonunda uygulama, işlemin işlenmesini veya geri alınmasını ister. Ağ hatasının bazı kaynak yöneticilerinin işlemi başarıyla gerçekleştirmesine, diğerlerinin ise işlemi geri almasına neden olma riskini en aza indirmek için dağıtılmış bir işlemin işlem yöneticisi tarafından farklı bir şekilde yönetilmesi gerekir. Bu, işleme işlemini iki aşamalı işleme olarak bilinen iki aşamada (hazırlama aşaması ve işleme aşaması) yöneterek elde edilir.
Hazırlama aşaması
İşlem yöneticisi bir işleme isteği aldığında, işlemde yer alan tüm kaynak yöneticilerine bir hazırlama komutu gönderir. Ardından her kaynak yöneticisi işlemi dayanıklı hale getirmek için gereken her şeyi yapar ve işlem için tüm işlem günlüğü arabellekleri diske boşaltılır. Her kaynak yöneticisi hazırlama aşamasını tamamlarken aşamanın başarısını veya başarısızlığını işlem yöneticisine döndürür. SQL Server 2014 (12.x) gecikmeli işlem dayanıklılığını kullanıma sunar. Gecikmeli dayanıklı işlemler, her kaynak yöneticisindeki işlem günlüğü arabellekleri diske boşaltilmeden önce işler. Gecikmeli işlem dayanıklılığı hakkında daha fazla bilgi için İşlem Dayanıklılığını Denetlememakalesine bakın.
Taahhüt aşaması
İşlem yöneticisi tüm kaynak yöneticilerinden başarılı hazırlıklar alırsa, her kaynak yöneticisine işleme komutları gönderir. Kaynak yöneticileri daha sonra işlemeyi tamamlayabilir. Tüm kaynak yöneticileri başarılı bir işleme raporlarsa, işlem yöneticisi uygulamaya bir başarı bildirimi gönderir. Herhangi bir kaynak yöneticisi hazırlanma hatası bildirdiyse, işlem yöneticisi her kaynak yöneticisine bir geri alma komutu gönderir ve uygulamaya işlemenin başarısız olduğunu gösterir.
Veritabanı Altyapısı uygulamaları dağıtılmış işlemleri Transact-SQL veya veritabanı API'si aracılığıyla yönetebilir. Daha fazla bilgi için bkz. BEGIN DISTRIBUTED TRANSACTION (Transact-SQL).
İşlemleri sonlandır
İşlemleri COMMIT veya ROLLBACK deyimiyle veya karşılık gelen bir API işlevi aracılığıyla sonlandırabilirsiniz.
İşleme
İşlem başarılı olursa, işlemi yürüt.
COMMIT
deyimi, işlemin tüm değişikliklerinin veritabanının kalıcı bir parçası haline getirildiğinden emin olur. Bir işlem, transaction tarafından kullanılan kilitler gibi kaynakları da serbest bırakır.geri al
Bir işlemde hata oluşursa veya kullanıcı işlemi iptal etmeye karar verirse işlemi geri alın.
ROLLBACK
deyimi, verileri işlemin başlangıcındaki durumuna döndürerek işlemde yapılan tüm değişiklikleri geri alır. Geri alma işlemi, işlem tarafından tutulan kaynakları da serbest bırakır.
Not
Birden çok etkin sonuç kümesi (MARS) oturumunda, bekleyen yürütme istekleri varken bir API işlevi aracılığıyla başlatılan açık bir işlem tamamlanamaz. İstekler yürütülürken bu işlem türünü işleme girişimi bir hatayla sonuçlanır.
İşlem işleme sırasında hatalar
Hata bir işlemin başarıyla tamamlanmasını engellerse, Veritabanı Altyapısı işlemi otomatik olarak geri alır ve işlem tarafından tutulan tüm kaynakları boşaltır. Veritabanı Altyapısı'nın bir örneğine olan istemci ağ bağlantısı kesilirse, ağ, bağlantı kopmasını örneğe bildirdiğinde bağlantıya ait bekleyen tüm işlemler geri alınır. İstemci uygulaması başarısız olursa veya istemci bilgisayar kapanırsa veya yeniden başlatılırsa, bu bağlantı da kesilir ve ağ bağlantının kesileceğini bildirirken Veritabanı Altyapısı örneği kalan işlemleri geri alır. İstemcinin Veritabanı Altyapısı bağlantısını kesmesi durumunda bekleyen işlemler geri alınır.
Bir toplu işlemde bir çalışma zamanı deyimi hatası (kısıtlama ihlali gibi) oluşursa, Veritabanı Altyapısı'ndaki varsayılan davranış yalnızca hatayı oluşturan deyimi geri almaktır.
SET XACT_ABORT ON
deyimini kullanarak bu davranışı değiştirebilirsiniz.
SET XACT_ABORT ON
yürütüldükten sonra, herhangi bir çalışma zamanı ifadesi hatası mevcut işlemin otomatik olarak geri alınmasına neden olur. Söz dizimi hataları gibi derleme hataları SET XACT_ABORT
etkilenmez. Daha fazla bilgi için bkz. SET XACT_ABORT (Transact-SQL).
Hatalar oluştuğunda, uygulama koduna uygun eylem (COMMIT
veya ROLLBACK
) eklenmelidir. İşlemlerdeki hatalar da dahil olmak üzere hataları işlemek için etkili araçlardan biri Transact-SQL TRY...CATCH
yapısıdır. İşlemleri içeren örneklerle ilgili daha fazla bilgi için bkz. TRY... CATCH (Transact-SQL). SQL Server 2012'den (11.x) başlayarak THROW
deyimini kullanarak özel durum oluşturabilir ve yürütmeyi bir CATCH
yapısının TRY...CATCH
bloğuna aktarabilirsiniz. Daha fazla bilgi için bkz. THROW (Transact-SQL).
Otomatik komut modunda derleme ve çalışma zamanı hataları
Otomatik işleme modunda, bazen Veritabanı Altyapısı örneğinin yalnızca bir SQL deyimi yerine tüm bir işlemi geri almış gibi görünebilir. Karşılaşılan hata bir derleme hatasıysa, çalışma zamanı hatası değilse bu durum oluşur. Derleme hatası, Veritabanı Altyapısı'nın bir yürütme planı oluşturmasını engeller, bu nedenle toplu işlemdeki hiçbir şey yürütülemez. Hatayı oluşturan deyimden önceki tüm ifadelerin geri alındığı görünse de, hata toplu işteki herhangi bir şeyin yürütülmesini engelledi. Aşağıdaki örnekte, derleme hatası nedeniyle üçüncü toplu işlemdeki INSERT
deyimlerinin hiçbiri yürütülmez. Görünüşe göre ilk iki INSERT
deyimi hiçbir zaman yürütülmediğinde geri alınmış oluyor.
CREATE TABLE TestBatch (ColA INT PRIMARY KEY, ColB CHAR(3));
GO
INSERT INTO TestBatch VALUES (1, 'aaa');
INSERT INTO TestBatch VALUES (2, 'bbb');
INSERT INTO TestBatch VALUSE (3, 'ccc'); -- Syntax error.
GO
SELECT * FROM TestBatch; -- Returns no rows.
GO
Aşağıdaki örnekte, üçüncü INSERT
deyimi çalışma zamanı yinelenen birincil anahtar hatası oluşturur. İlk iki INSERT
deyimi başarılı ve commit edilir, bu nedenle hata meydana geldikten sonra kalırlar.
CREATE TABLE TestBatch (ColA INT PRIMARY KEY, ColB CHAR(3));
GO
INSERT INTO TestBatch VALUES (1, 'aaa');
INSERT INTO TestBatch VALUES (2, 'bbb');
INSERT INTO TestBatch VALUES (1, 'ccc'); -- Duplicate key error.
GO
SELECT * FROM TestBatch; -- Returns rows 1 and 2.
GO
Veritabanı Altyapısı, nesne adlarının derleme zamanında değil yürütme zamanında çözümlendiği ertelenen ad çözümlemesini kullanır. Aşağıdaki örnekte, ilk iki INSERT
deyimi yürütülür ve kaydedilir, ve üçüncü TestBatch
deyimi var olmayan bir tabloya başvurarak çalışma zamanı hatası oluşturduktan sonra bu iki satır INSERT
tablosunda kalır.
CREATE TABLE TestBatch (ColA INT PRIMARY KEY, ColB CHAR(3));
GO
INSERT INTO TestBatch VALUES (1, 'aaa');
INSERT INTO TestBatch VALUES (2, 'bbb');
INSERT INTO TestBch VALUES (3, 'ccc'); -- Table name error.
GO
SELECT * FROM TestBatch; -- Returns rows 1 and 2.
GO
Kilitleme ve satır sürümü yönetimi ile ilgili temel bilgiler
Veritabanı Altyapısı, işlemlerin bütünlüğünü sağlamak ve birden çok kullanıcı aynı anda verilere erişirken veritabanlarının tutarlılığını korumak için aşağıdaki mekanizmaları kullanır:
Kilitleme
Her işlem, işlemin bağımlı olduğu satırlar, sayfalar veya tablolar gibi kaynaklarda farklı türlerde kilitler ister. Kilitler, diğer işlemlerin kaynakları kilit isteğinde bulunan işlem için sorunlara neden olacak şekilde değiştirmesini engeller. Her işlem, kilitli kaynaklara bağımlılığı kalmadığında kilitlerini serbest bırakır.
Satır sürüm oluşturma
Satır sürüm oluşturma tabanlı yalıtım düzeyi kullanıldığında, Veritabanı Altyapısı değiştirilen her satırın sürümlerini korur. Uygulamalar, bir işlemin, tüm okumaları kilitlerle korumak yerine, işlem veya deyimin başında mevcut olan verileri görüntülemek için satır sürümlerini kullanmasını belirtebilir. Satır sürümü oluşturma kullanıldığında, okuma işleminin diğer işlemleri engelleme olasılığı büyük ölçüde azalır.
Kilitleme ve satır sürümü oluşturma, kullanıcıların kaydedilmemiş verileri okumasını ve birden çok kullanıcının aynı anda aynı verileri değiştirmeyi denemesini engeller. Kilitleme veya satır sürümü oluşturma olmadan, bu verilerde yürütülen sorgular veritabanında henüz işlenmemiş verileri döndürerek beklenmeyen sonuçlara neden olabilir.
Uygulamalar, diğer işlemler tarafından yapılan değişikliklerden işlem için koruma düzeyini tanımlayan işlem yalıtım düzeylerini seçebilir. Davranışı uygulamanın gereksinimlerine uyacak şekilde daha da uyarlamak için tek tek Transact-SQL deyimleri için tablo düzeyinde ipuçları belirtilebilir.
Eşzamanlı veri erişimini yönetme
Bir kaynağa aynı anda erişen kullanıcıların kaynağa eşzamanlı olarak eriştiği söylenir. Eşzamanlı veri erişimi, birden çok kullanıcı diğer kullanıcıların etkin olarak kullandığı kaynakları değiştirmeye çalıştığında olumsuz etkileri önlemek için mekanizmalar gerektirir.
Eşzamanlılık etkileri
Verileri değiştiren kullanıcılar, aynı anda aynı verileri okuyan veya değiştiren diğer kullanıcıları etkileyebilir. Bu kullanıcıların verilere eşzamanlı olarak eriştiği söylenir. Bir veritabanında eşzamanlılık denetimi yoksa, kullanıcılar aşağıdaki yan etkileri görebilir:
kaybolan güncellemeler
Kayıp güncelleştirmeler, iki veya daha fazla işlem aynı satırı seçip başlangıçta seçilen değere göre satırı güncelleştirdiğinde gerçekleşir. Her işlem diğer işlemlerin farkında değildir. Son güncelleştirme, diğer işlemler tarafından yapılan güncelleştirmelerin üzerine yazılır ve bu da verilerin kaybolmasına neden olur.
Örneğin, iki düzenleyici aynı belgenin elektronik kopyasını oluşturur. Her düzenleyici kopyayı bağımsız olarak değiştirir ve değiştirilen kopyayı kaydederek özgün belgenin üzerine yazar. Değiştirilen kopyayı en son kaydeden düzenleyici, diğer düzenleyici tarafından yapılan değişikliklerin üzerine yazar. Bu sorun, bir düzenleyici diğer düzenleyici işlemi tamamlayıp işleyene kadar dosyaya erişemezse önlenebilir.
Tamamlanmamış bağımlılık (kirli okuma)
Onaylanmamış bağımlılık, ikinci bir işlem başka bir işlem tarafından güncellenmekte olan bir satırı okuduğunda ortaya çıkar. İkinci işlem, henüz taahhüt edilmemiş olan ve satırı güncelleyebilecek işlem tarafından değiştirilebilen verileri okumaktır.
Örneğin, bir düzenleyici elektronik belgede değişiklik yapıyor. Değişiklikler sırasında, ikinci bir düzenleyici belgenin şimdiye kadar yapılan tüm değişiklikleri içeren bir kopyasını alır ve belgeyi hedeflenen hedef kitleye dağıtır. İlk düzenleyici daha sonra şu ana kadar yapılan değişikliklerin yanlış olduğunu karar verir ve düzenlemeleri kaldırır ve belgeyi kaydeder. Dağıtılmış belge artık var olmayan düzenlemeler içeriyor ve bunlar hiç varolmamış gibi ele alınmalıdır. İlk düzenleyici son değişiklikleri kaydedip işlemi işleyene kadar değiştirilen belgeyi kimse okuyamazsa bu sorun önlenebilir.
Tutarsız analiz (tekrarlanamayan okuma)
Tutarsız analiz, ikinci bir işlem aynı satıra birkaç kez eriştiğinde ve her seferinde farklı verileri okuduğunda oluşur. Tutarsız analiz, başka bir işlemin ikinci bir işlemin okuduğu verileri değiştirmesindeki kaydedilmemiş bağımlılıkla benzerdir. Ancak tutarsız analizde, ikinci işlem tarafından okunan veriler değişikliği yapan işlem tarafından işlendi. Ayrıca, tutarsız okuma, aynı satırın birden fazla kez (iki veya daha fazla) okunmasını içerir ve her seferinde bilgiler başka bir işlem tarafından değiştirilir; bu nedenle, tekrar edilemez okuma terimi kullanılır.
Örneğin, bir düzenleyici aynı belgeyi iki kez okur, ancak her okuma arasında yazıcı belgeyi yeniden yazar. Düzenleyici belgeyi ikinci kez okuduğunda değişmiştir. Özgün okuma yinelenemedi. Düzenleyici son kez okumayı bitirene kadar yazıcı belgeyi değiştiremezse bu sorun önlenebilir.
Phantom okur
Hayalet okuma, iki özdeş sorgu yürütülürken ve ikinci sorgu tarafından döndürülen satır kümesi farklı olduğunda oluşan bir durumdur. Aşağıdaki örnekte bunun nasıl gerçekleşebileceği gösterilmektedir. İki işlemin aynı anda yürütülmekte olduğunu varsayalım. İkinci işlemdeki
SELECT
deyimi her ikisi tarafından kullanılan verileri değiştirdiğinden, ilk işlemdeki ikiINSERT
deyimi farklı sonuçlar döndürebilir.--Transaction 1 BEGIN TRAN; SELECT ID FROM dbo.employee WHERE ID > 5 AND ID < 10; --The INSERT statement from the second transaction occurs here. SELECT ID FROM dbo.employee WHERE ID > 5 and ID < 10; COMMIT;
--Transaction 2 BEGIN TRAN; INSERT INTO dbo.employee (Id, Name) VALUES(6 ,'New'); COMMIT;
Satır güncelleştirmelerinin neden olduğu eksik ve çift okuma
Güncellenmiş bir satırın eksik olması veya güncellenmiş bir satırı birden çok kez görmek
READ UNCOMMITTED
düzeyinde çalışan işlemler (veyaNOLOCK
tablo ipucunu kullanan deyimler), diğer işlemlerin geçerli işlem tarafından okunan verileri değiştirmesini önlemek için paylaşılan kilitler vermez.READ COMMITTED
düzeyinde çalışan işlemler paylaşılan kilitler oluşturur, ancak satır veya sayfa kilitleri satır okunduktan sonra serbest bırakılır. Her iki durumda da, bir dizini tararken, okuma sırasında başka bir kullanıcı satırın dizin anahtarı sütununu değiştirirse, anahtar değişikliği satırı taramanızın önündeki bir konuma taşırsa satır yeniden görünebilir. Benzer şekilde, anahtar değişikliği satırı daha önce okuduğunuz dizindeki bir konuma taşıdıysa satır hiç okunamayabilir. Bunu önlemek içinSERIALIZABLE
veyaHOLDLOCK
ipucunu ya da satır sürümü oluşturma özelliğini kullanın. Daha fazla bilgi için bkz. Tablo İpuçları (Transact-SQL).Güncelleştirmenin hedefi olmayan bir veya daha fazla satır eksik
READ UNCOMMITTED
kullanırken, sorgunuz bir atama sırası taraması (IAM sayfalarını kullanarak) ile satırları okuyorsa ve başka bir işlem sayfa bölünmesine sebep oluyorsa, bazı satırları kaçırabilirsiniz. Bu durum,READ COMMITTED
yalıtım düzeyini kullandığınızda gerçekleşmez.
Eşzamanlılık türleri
Birden çok işlem aynı anda veritabanındaki verileri değiştirmeye çalıştığında, bir işlem tarafından yapılan değişikliklerin başka bir işlemin değişikliklerini olumsuz etkilememesi için bir denetim sistemi uygulanmalıdır. Buna eşzamanlılık denetimi denir.
Eşzamanlılık denetimi teorisi, eşzamanlılık denetimi oluşturma yöntemleri için iki sınıflandırmaya sahiptir:
Kötümser eşzamanlılık denetimi
Kilit sistemi, işlemlerin verileri diğer işlemleri etkileyecek şekilde değiştirmesini engeller. Bir işlem bir kilidin uygulanmasına neden olan bir eylem gerçekleştirdikten sonra, diğer işlemler sahibi onu serbest bırakana kadar kilitle çakışacak eylemleri gerçekleştiremez. Buna kötümser denetim denir, çünkü genellikle veriler için yüksek çekişme olan sistemlerde kullanılır ve burada verileri kilitlerle koruma maliyeti, eşzamanlılık çakışmaları oluşursa işlemleri geri alma maliyetinden daha düşüktür.
İyimser eşzamanlılık denetimi
İyimser eşzamanlılık denetiminde işlemler verileri okurken kilitlemez. Ancak bir işlem verileri güncelleştirdiğinde sistem, okunduktan sonra başka bir işlemin verileri değiştirip değiştirmediğini denetler. Başka bir işlem verileri güncelleştirdiyse bir hata oluşur. Genellikle, hata alan işlem geri alınır ve işlem baştan başlar. Bu, genellikle veriler üzerinde düşük çekişmenin olduğu ve zaman zaman bir işlemi geri almanın maliyetinin veri okunduğunda verileri kilitleme maliyetinden daha düşük olduğu sistemlerde kullanıldığından iyimser olarak adlandırılır.
Veritabanı Altyapısı her iki eşzamanlılık denetimi yöntemini de destekler. Kullanıcılar, bağlantılar için işlem yalıtım düzeylerini veya imleçlerdeki eşzamanlılık seçeneklerini seçerek eşzamanlılık denetiminin türünü belirtir. Bu öznitelikler Transact-SQL deyimleri kullanılarak veya ADO, ADO.NET, OLE DB ve ODBC gibi veritabanı uygulama programlama arabirimlerinin (API' ler) özellikleri ve öznitelikleri aracılığıyla tanımlanabilir.
Veritabanı Altyapısı'nda yalıtım düzeyleri
İşlemler, bir işlemin kaynaktan yalıtılması gereken dereceyi veya diğer işlemler tarafından yapılan veri değişikliklerini tanımlayan bir yalıtım düzeyi belirtir. Yalıtım düzeyleri, kirli okumalar veya hayalet okumalar gibi eşzamanlılık yan etkilerine izin verilenler açısından açıklanmıştır.
İşlem yalıtım düzeyleri denetimi:
- Veriler okunduğunda kilitlerin alınıp alınmayacağı ve ne tür kilitlerin istendiği.
- Okuma kilitlerinin ne kadar süre tutulduğu.
- Başka bir işlem tarafından değiştirilen satırlara başvuran bir okuma işleminin olup olmadığı:
- Satırdaki özel kilit serbest olana kadar engeller.
- Deyimin veya işlemin başladığı sırada var olan satırın kaydedilmiş sürümünü alır.
- Kaydedilmemiş veri değişikliğini okur.
Önemli
İşlem yalıtım düzeyinin seçilmesi, veri değişikliklerini korumak için alınan kilitleri etkilemez. İşlem, veri değişikliği gerçekleştirmek için her zaman bir özel kilit tutar ve işlem için ayarlanan yalıtım düzeyi ne olursa olsun işlem tamamlanana kadar bu kilidi tutar. Okuma işlemleri için, işlem yalıtım düzeyleri öncelikli olarak diğer işlemler tarafından yapılan değişikliklerin etkilerine karşı koruma düzeyini tanımlar.
Düşük yalıtım düzeyi, birçok işlemin aynı anda verilere erişme becerisini artırır, ancak aynı zamanda eşzamanlılık etkilerinin (kirli okumalar veya kayıp güncelleştirmeler gibi) karşılaşabileceği işlemlerin sayısını da artırır. Buna karşılık, daha yüksek bir yalıtım düzeyi işlemlerin karşılaşabileceği eşzamanlılık etkisi türlerini azaltır, ancak daha fazla sistem kaynağı gerektirir ve bir işlemin diğerini engelleme olasılığını artırır. Uygun yalıtım düzeyinin seçilmesi, uygulamanın veri bütünlüğü gereksinimlerini her yalıtım düzeyinin yüküne göre dengelemeye bağlıdır.
SERIALIZABLE
en yüksek yalıtım düzeyi, bir işlemin bir okuma işlemini her yinelediğinden tam olarak aynı verileri almasını garanti eder, ancak bunu çok kullanıcılı sistemlerdeki diğer işlemleri etkileme olasılığı olan bir kilitleme düzeyi gerçekleştirerek gerçekleştirir. Diğer işlemler tarafından değiştirilmiş ancak onaylanmamış verileri alabilen en düşük yalıtım düzeyi READ UNCOMMITTED
'dır. Eşzamanlılık yan etkilerinin tümü READ UNCOMMITTED
içinde gerçekleşebilir, ancak okuma kilitleme veya sürüm oluşturma yoktur, bu nedenle ek yük en aza indirilir.
Veritabanı Altyapısı yalıtım düzeyleri
ISO standardı aşağıdaki yalıtım düzeylerini tanımlar ve bunların tümü Veritabanı Altyapısı tarafından desteklenir:
Yalıtım Düzeyi | Tanım |
---|---|
READ UNCOMMITTED |
İşlemlerin yalnızca fiziksel olarak tutarsız verilerin okunmamasını sağlayacak kadar yalıtıldığı en düşük yalıtım düzeyi. Bu düzeyde kirli okumalara izin verilir, bu yüzden bir işlem, diğer işlemler tarafından henüz onaylanmamış değişiklikleri görebilir. |
READ COMMITTED |
bir işlemin, ilk işlemin tamamlanmasını beklemeden başka bir işlem tarafından daha önce okunan (değiştirilmeyen) verileri okumasına izin verir. Veritabanı Altyapısı, yazma kilitlerini (seçili verilerde alınan) işlemin sonuna kadar tutar, ancak okuma işlemi gerçekleştiğinde okuma kilitleri serbest bırakılır. Bu, Veritabanı Altyapısı varsayılan düzeyidir. |
REPEATABLE READ |
Veritabanı Altyapısı, seçilen veriler üzerinde alınan okuma ve yazma kilitlerini işlemin sonuna kadar tutar. Ancak, aralık kilitleri yönetilmediğinden, hayalet okumalar oluşabilir. |
SERIALIZABLE |
İşlemlerin birbirinden tamamen yalıtıldığı en yüksek düzey. Veritabanı Altyapısı, seçilen veriler üzerinde alınan okuma ve yazma kilitlerini işlemin sonuna kadar tutar. Bir SELECT işlemi, hayalet okumaları önlemek için bir aralık WHERE yan tümcesi kullandığında aralık kilitleri elde edilir. DDL işlemleri ve çoğaltılan tablolardaki işlemler başarısız olabilir. Bunun nedeni çoğaltma sorgularının SERIALIZABLE yalıtım düzeyiyle uyumsuz olabilecek ipuçları kullanmasıdır. |
Veritabanı Altyapısı, satır sürümü oluşturma kullanan iki ek işlem yalıtım düzeyini de destekler. Biri READ COMMITTED
yalıtım düzeyinin bir uygulaması, diğeri de SNAPSHOT
işlem yalıtım düzeyidir.
Satır Sürüm Oluşturma Yalıtım Düzeyi | Tanım |
---|---|
Read Committed Snapshot (RCSI) |
READ_COMMITTED_SNAPSHOT veritabanı seçeneği Azure SQL Veritabanı'ndaki varsayılan ayar olan ON ayarlandığında, READ COMMITTED yalıtım düzeyi deyim düzeyinde okuma tutarlılığı sağlamak için satır sürümü oluşturma özelliğini kullanır. Okuma işlemleri için yalnızca şema kararlılığı (Sch-S ) tablo düzeyi kilitleri gerekir ve sayfa veya satır kilidi yoktur. Yani, Veritabanı Motoru, her ifadenin başında mevcut olan verilerin işlemsel olarak tutarlı bir anlık görüntüsünü sunmak için satır sürümleme kullanır. Kilitler, verileri diğer işlemler tarafından yapılan güncelleştirmelerden korumak için kullanılmaz. Kullanıcı tanımlı bir işlev, UDF'yi içeren deyimin başlamasından sonra işlenen verileri döndürebilir.READ_COMMITTED_SNAPSHOT veritabanı seçeneği, SQL Server ve Azure SQL Yönetilen Örneği'nde varsayılan ayar olan OFF olarak ayarlandığında, READ COMMITTED yalıtımı, geçerli işlem bir okuma işlemi gerçekleştirirken diğer işlemlerin satırları değiştirmesine engel olmak amacıyla paylaşılan kilitler kullanır. Paylaşılan kilitler, diğer işlem tamamlanana kadar deyimin diğer işlemler tarafından değiştirilen satırları okumasını da engeller. Her iki uygulama da READ COMMITTED yalıtımının ISO tanımını karşılar. |
SNAPSHOT |
Anlık görüntü yalıtım düzeyi, işlem düzeyi okuma tutarlılığı sunmak için satır sürümü kullanır. Okuma işlemleri hiçbir sayfa veya satır kilidi almaz; yalnızca şema kararlılığı (Sch-S ) tablo kilitleri alınır. Başka bir işlem tarafından değiştirilen satırları okurken, okuma işlemleri işlem başlatıldığında var olan satırın sürümünü alır.
SNAPSHOT yalıtımını yalnızca ALLOW_SNAPSHOT_ISOLATION veritabanı seçeneği ON olarak ayarlandığında kullanabilirsiniz. Varsayılan olarak, bu seçenek SQL Server ve Azure SQL Yönetilen Örneği'ndeki kullanıcı veritabanları için OFF olarak ayarlanır ve Azure SQL Veritabanı'ndaki veritabanları için ON olarak ayarlanır.Not: Veritabanı Altyapısı meta verilerin sürüm oluşturmasını desteklemez. Bu nedenle, anlık görüntü yalıtımı altında çalışan açık bir işlemde hangi DDL işlemlerinin gerçekleştirilebileceğine ilişkin kısıtlamalar vardır. BEGIN TRANSACTION deyiminden sonra anlık görüntü yalıtımı altında aşağıdaki DDL deyimlerine izin verilmez: ALTER TABLE , CREATE INDEX , CREATE XML INDEX , ALTER INDEX , DROP INDEX , DBCC REINDEX , ALTER PARTITION FUNCTION , ALTER PARTITION SCHEME veya herhangi bir ortak dil çalışma zamanı (CLR) DDL deyimi. Örtük işlemler içinde anlık görüntü izolasyonu kullanırken bu ifadelere izin verilir. Tanım gereği örtük bir işlem, DDL deyimleriyle bile anlık görüntü yalıtımı semantiğini zorunlu kılmayı mümkün kılan tek bir deyimdir. Bu ilkenin ihlalleri 3961: Snapshot isolation transaction failed in database '%.*ls' because the object accessed by the statement has been modified by a DDL statement in another concurrent transaction since the start of this transaction. It is not allowed because the metadata is not versioned. A concurrent update to metadata could lead to inconsistency if mixed with snapshot isolation. hatasına neden olabilir |
Aşağıdaki tabloda, farklı yalıtım düzeylerinin etkinleştirdiği eşzamanlılık yan etkileri gösterilmektedir.
Yalıtım düzeyi | Kirli okuma | Tekrarlanamaz okuma | Hayalet |
---|---|---|---|
READ UNCOMMITTED |
Evet | Evet | Evet |
READ COMMITTED |
Hayır | Evet | Evet |
REPEATABLE READ |
Hayır | Hayır | Evet |
SNAPSHOT |
Hayır | Hayır | Hayır |
SERIALIZABLE |
Hayır | Hayır | Hayır |
İşlem yalıtım seviyelerinin denetlediği belirli kilitleme veya satır sürümü oluşturma türleri hakkında daha fazla bilgi için bkz. SET TRANSACTION ISOLATION LEVEL (Transact-SQL).
İşlem yalıtım düzeyleri Transact-SQL kullanılarak veya veritabanı API'si aracılığıyla ayarlanabilir.
Transact-SQL
Transact-SQL betikler SET TRANSACTION ISOLATION LEVEL
deyimini kullanır.
ADO
ADO uygulamaları, IsolationLevel
nesnesinin Connection
özelliğini adXactReadUncommitted
, adXactReadCommitted
, adXactRepeatableRead
veya adXactReadSerializable
olarak ayarlar.
ADO.NET
System.Data.SqlClient
yönetilen ad alanını kullanan ADO.NET uygulamalar SqlConnection.BeginTransaction
yöntemini çağırabilir ve IsolationLevel
seçeneğini Unspecified
, Chaos
, ReadUncommitted
, ReadCommitted
, RepeatableRead
, Serializable
veya Snapshot
olarak ayarlayabilir.
OLE DB
İşlem başlatırken, OLE DB kullanan uygulamalar, ITransactionLocal::StartTransaction
'ı isoLevel
'i ISOLATIONLEVEL_READUNCOMMITTED
, ISOLATIONLEVEL_READCOMMITTED
, ISOLATIONLEVEL_REPEATABLEREAD
, ISOLATIONLEVEL_SNAPSHOT
veya ISOLATIONLEVEL_SERIALIZABLE
olarak ayarlayarak çağırırlar.
OTOMATIK komut modunda işlem yalıtım düzeyini belirtirken, OLE DB uygulamaları DBPROPSET_SESSION
özellik DBPROP_SESS_AUTOCOMMITISOLEVELS
DBPROPVAL_TI_CHAOS
, DBPROPVAL_TI_READUNCOMMITTED
, DBPROPVAL_TI_BROWSE
, DBPROPVAL_TI_CURSORSTABILITY
, DBPROPVAL_TI_READCOMMITTED
, DBPROPVAL_TI_REPEATABLEREAD
, DBPROPVAL_TI_SERIALIZABLE
, DBPROPVAL_TI_ISOLATED
veya DBPROPVAL_TI_SNAPSHOT
olarak ayarlayabilir.
ODBC
ODBC uygulamaları, SQLSetConnectAttr
Attribute
ve SQL_ATTR_TXN_ISOLATION
ValuePtr
, SQL_TXN_READ_UNCOMMITTED
, SQL_TXN_READ_COMMITTED
veya SQL_TXN_REPEATABLE_READ
olarak ayarlanmış olarak SQL_TXN_SERIALIZABLE
çağırır.
Anlık görüntü işlemleri için uygulamalar, SQLSetConnectAttr
'ı çağırırlar ve özniteliği SQL_COPT_SS_TXN_ISOLATION
, ValuePtr
'yi SQL_TXN_SS_SNAPSHOT
olarak ayarlayın. Anlık görüntü işlemi SQL_COPT_SS_TXN_ISOLATION
veya SQL_ATTR_TXN_ISOLATION
kullanılarak erişilebilir.
Veritabanı Altyapısında Kilitleme
Kilitleme, Veritabanı Altyapısı tarafından birden çok kullanıcının aynı veri parçasına erişimi aynı anda eşitlemek için kullanılan bir mekanizmadır.
Bir işlem, verileri okuyarak veya değiştirerek veri parçasının geçerli durumuna bağımlılık elde etmeden önce, kendisini aynı verileri değiştiren başka bir işlemin etkilerinden korumalıdır. İşlem bunu veri parçası üzerinde kilit isteğinde bulunarak yapar. Kilitler paylaşılan (S
) veya özel (X
) gibi farklı modlara sahiptir. Kilit modu, işlemin veriler üzerindeki bağımlılık düzeyini tanımlar. Hiçbir işleme, başka bir işleme verilerde zaten verilmiş olan bir kilidin moduyla çakışan bir kilit verilemiyor. Bir işlem aynı verilerde zaten verilmiş olan bir kilitle çakışan bir kilit modu talep ederse, Veritabanı Motoru ilk kilit serbest bırakılana kadar talep eden işlemi durdurur.
Bir işlem bir veri parçasını değiştirdiğinde, işlemin sonuna kadar değişikliği koruyan belirli kilitleri tutar. Bir işlemin okuma işlemlerini korumak için aldığı kilitleri ne kadar süre tuttuğu, işlem yalıtım düzeyi ayarına ve iyileştirilmiş kilitleme'nin etkinleştirilmiş olup olmadığına bağlıdır.
İyileştirilmiş kilitleme etkinleştirilmediğinde, yazma işlemleri için gereken satır ve sayfa kilitleri işlemin sonuna kadar tutulur.
İyileştirilmiş kilitleme etkinleştirildiğinde, işlemin sonuna kadar yalnızca bir İşlem Kimliği (TID) kilidi tutulur. Varsayılan
READ COMMITTED
yalıtım düzeyi altında işlemler, işlemin sonuna kadar yazma işlemleri için gereken satır ve sayfa kilitlerini tutmaz. Bu, gereken kilit belleğini azaltır ve kilit yükseltme gereksinimini azaltır. Ayrıca, optimize edilmiş kilitleme etkinleştirildiğinde, nitelemeden sonra kilidi (LAQ) optimizasyonu, sorgunun bir satırın en son işlenen sürümündeki önermelerini bir kilit almadan değerlendirir ve böylece eşzamanlılığı artırır.
İşlem tamamlandığında, bir işlem tarafından tutulan tüm kilitler serbest bırakılır (ya tamamlanır ya da iptal edilir).
Uygulamalar genellikle doğrudan kilit isteğinde bulunmaz. Kilitler, Veritabanı Altyapısı'nın kilit yöneticisi adı verilen bir bölümü tarafından dahili olarak yönetilir. Veritabanı Altyapısı örneği bir Transact-SQL deyimini işlediğinde, Veritabanı Altyapısı sorgu işlemcisi hangi kaynaklara erişileceğini belirler. Sorgu işlemcisi, erişim türüne ve işlem yalıtım düzeyi ayarına göre her kaynağı korumak için gereken kilit türlerini belirler. Sorgu işlemcisi daha sonra kilit yöneticisinden uygun kilitleri istemektedir. Diğer işlemler tarafından tutulan çakışan kilitler yoksa, kilit yöneticisi kilitleri verir.
Ayrıntı düzeyini ve hiyerarşileri kilitleme
Veritabanı Altyapısı, farklı kaynak türlerinin bir işlem tarafından kilitlenmesine olanak tanıyan çok boyutlu kilitlemeye sahiptir. Veritabanı Altyapısı, kilitleme maliyetini en aza indirmek için kaynakları göreve uygun bir düzeyde otomatik olarak kilitler. Satırlar gibi daha küçük bir ayrıntı düzeyinde kilitlemek eşzamanlılığı artırır, ancak çok sayıda satır kilitliyse daha fazla kilit tutulması gerektiğinden daha fazla ek yüke sahiptir. Tablo gibi daha büyük bir ayrıntı düzeyinde kilitlemek eşzamanlılık açısından pahalıdır çünkü tablonun tamamını kilitlemek tablonun herhangi bir bölümüne erişimi diğer işlemlere göre kısıtlar. Ancak, daha az kilit tutulacağından daha düşük ek yüke sahiptir.
Bir kaynağı tam olarak korumak için Veritabanı Altyapısı'nın genellikle birden çok ayrıntı düzeyinde kilit alması gerekir. Birden çok ayrıntı düzeyindeki bu kilit grubuna kilit hiyerarşisi adı verilir. Örneğin, bir dizinin okunmasını tam olarak korumak için, Veritabanı Motoru örneğinin satırlarda paylaşılan kilitler ve sayfa ile tabloda niyet edilen paylaşılan kilitler alması gerekebilir.
Aşağıdaki tabloda Veritabanı Altyapısı'nın kilitleyebileceği kaynaklar gösterilmektedir.
Kaynak | Açıklama |
---|---|
RID |
Yığın içindeki tek bir satırı kilitlemek için kullanılan satır tanımlayıcısı. |
KEY |
B ağacı dizinindeki tek bir satırı kilitlemek için satır kilidi. |
PAGE |
Veri veya dizin sayfaları gibi bir veritabanında 8 kilobaytlık (KB) sayfa. |
EXTENT |
Veri veya dizin sayfaları gibi sekiz sayfadan oluşan bitişik bir grup. |
HoBT
1 |
Bir yığın veya B ağacı. Kümelenmiş dizini olmayan bir tablodaki B ağacını (dizini) veya yığın veri sayfalarını koruyan kilit. |
TABLE
1 |
Tüm veriler ve dizinler de dahil olmak üzere tablonun tamamı. |
FILE |
Veritabanı dosyası. |
APPLICATION |
Uygulama tarafından belirtilen bir kaynak. |
METADATA |
Meta veri kilitleri. |
ALLOCATION_UNIT |
Ayırma birimi. |
DATABASE |
Bütün veritabanı. |
XACT
2 |
İşlem Kimliği (TID) kilidi İyileştirilmiş kilitleme'de kullanıldı. Daha fazla bilgi için bkz. İşlem Kimliği (TID) kilitleme. |
1HoBT
ve TABLE
kilitleri ALTER TABLE LOCK_ESCALATION
seçeneğinden etkilenebilir.
2XACT
kilit kaynakları için ek kilitleme kaynakları mevcuttur; bkz. İyileştirilmiş kilitleme için tanılama eklemeleri .
Kilit modları
Veritabanı Altyapısı, eşzamanlı işlemler tarafından kaynaklara nasıl erişilebileceğini belirleyen farklı kilit modlarını kullanarak kaynakları kilitler.
Aşağıdaki tabloda, Veritabanı Altyapısı'nın kullandığı kaynak kilidi modları gösterilmektedir.
Kilit modu | Açıklama |
---|---|
Paylaşılan (S ) |
SELECT deyimi gibi verileri değiştirmeyen veya güncelleştirmeyen okuma işlemleri için kullanılır. |
Güncelleştirme (U ) |
Güncelleştirilebilen kaynaklarda kullanılır. Birden çok oturum kaynakları okurken, kilitlerken ve potansiyel olarak güncellerken oluşan yaygın bir donma biçimini önler. |
Özel (X ) |
INSERT , UPDATE veya DELETE gibi veri değiştirme işlemleri için kullanılır. Aynı kaynakta aynı anda birden çok güncelleştirme yapılamamasını sağlar. |
Niyet | Kilit hiyerarşisi oluşturmak için kullanılır. Amaç kilidi türleri şunlardır: paylaşım amacı (IS ), özel amaç (IX ) ve özel amaçlı paylaşılan (SIX ). |
Şema | Bir tablonun şemasına bağımlı bir işlem yürütülürken kullanılır. Şema kilidi türleri şunlardır: şema değişikliği (Sch-M ) ve şema kararlılığı (Sch-S ). |
toplu güncelleştirme (BU ) |
TABLOCK ipucuyla verileri bir tabloya toplu olarak kopyalarken kullanılır. |
anahtar aralığı |
SERIALIZABLE işlem yalıtım düzeyini kullanırken sorgu tarafından okunan satır aralığını korur. Sorgular yeniden çalıştırılırsa, diğer işlemlerin SERIALIZABLE işleminin sorguları için uygun olan satırları ekleyememesini sağlar. |
Paylaşılan kilitler
Paylaşılan (S
) kilitleri, eşzamanlı işlemlerin kötümser eşzamanlılık denetimi altında bir kaynağı okumasına olanak sağlar. Kaynakta paylaşılan (S
) kilitler varken başka hiçbir işlem verileri değiştiremez. Bir kaynak üzerindeki Paylaşılan (S
) kilitleri, işlem yalıtım düzeyi REPEATABLE READ
veya daha yüksek olarak ayarlanmadığı veya paylaşılan (S
) kilitleri işlem süresi boyunca korumak için bir kilitleme ipucu kullanılmadığı sürece, okuma işlemi tamamlanır tamamlanmaz serbest bırakılır.
Kilitleri güncelleştirme
Veritabanı Motoru, bir güncelleştirme işlemi gerçekleştirmeye hazırlanırken güncelleştirme (U
) kilidini yerleştirir.
U
kilitler S
kilitlerle uyumludur, ancak belirli bir kaynakta tek seferde yalnızca bir işlem U
kilit tutabilir. Bu anahtardır- birçok eşzamanlı işlem S
kilitleri tutabilir, ancak yalnızca bir işlem bir kaynakta U
kilit tutabilir. Update (U
) kilitleri, bir satırı güncelleştirmek için zamanla özel (X
) kilitlere dönüştürülür.
Update (U
) kilitleri, UPDATE
deyiminde belirtildiğinde dışındaki deyimler tarafından da alınabilir.
Bazı uygulamalar, okuma ve yazma işlemlerinin işlem içinde açıkça ayrıldığı "bir satır seçin, sonra satırı güncelleştirin" desenini kullanır. Bu durumda, yalıtım düzeyi
REPEATABLE READ
veyaSERIALIZABLE
ise, eşzamanlı güncelleştirmeler aşağıdaki gibi kilitlenmeye neden olabilir:İşlem verileri okur, kaynak üzerinde paylaşılan (
S
) bir kilit alır ve ardından verileri değiştirir; bu da kilit dönüştürmeyi özel (X
) bir kilide dönüştürmeyi gerektirir. Eğer iki işlem bir kaynak üzerinde paylaşılan (S
) kilitler edinirse ve ardından verileri eşzamanlı olarak güncellemeye çalışırlarsa, bir işlem kilidi özel (X
) bir kilide dönüştürmeyi dener. Bir işlem için özel (X
) kilidi, diğer işlemin paylaşılan (S
) kilidiyle uyumlu olmadığından, paylaşılan kilidin özel kilide dönüştürülmesi beklemek zorundadır; bu durum kilit beklemesine yol açar. İkinci işlem, güncelleştirmesi için özel (X
) bir kilit almaya çalışır. Her iki işlem de özel (X
) kilitlere dönüştürüldüğünden ve her biri diğer işlemin paylaşılan (S
) kilidini serbest bırakmasını beklediğinden, kilitlenme oluşur.Varsayılan
READ COMMITTED
yalıtım düzeyinde,S
kilitler kısa sürelidir ve kullanıldıkları anda serbest bırakılır. Yukarıda açıklanan kilitlenme hala mümkün olsa da, kısa süreli kilitlerle çok daha az olasıdır.Bu tür bir kilitlenmeyi önlemek için, uygulamalar "
UPDLOCK
ipucu içeren bir satır seçin, ardından satırı güncelleştirin" desenini izleyebilir.UPDLOCK
ipucu,SNAPSHOT
yalıtımı kullanılırken bir yazma işlemi sırasında kullanılırsa, transaksiyonun satırın en son sürümüne erişimi olması gerekir. En son sürüm artık görünmüyorsa,Msg 3960, Level 16, State 2 Snapshot isolation transaction aborted due to update conflict
almak mümkündür. Örnek için bkz. Anlık görüntü yalıtımıyla çalışma.
Özel kilitler
Özel (X
) kilitleri eşzamanlı işlemler tarafından bir kaynağa erişimi engeller. Özel (X
) bir kilit ile, kilit tarafından korunan verileri başka hiçbir işlem değiştiremez; okuma işlemleri yalnızca NOLOCK
ipucunun veya READ UNCOMMITTED
yalıtım düzeyinin kullanılmasıyla gerçekleşebilir.
INSERT
, UPDATE
ve DELETE
gibi veri değişikliği deyimleri hem okuma hem de değiştirme işlemlerini birleştirir. deyimi, gerekli değişiklik işlemlerini gerçekleştirmeden önce verileri almak için önce okuma işlemleri gerçekleştirir. Bu nedenle veri değişikliği deyimleri genellikle hem paylaşılan kilitleri hem de özel kullanım kilitlerini isteyebilir. Örneğin, bir UPDATE
deyimi, başka bir tabloyla birleştirmeyi temel alarak bir tablodaki satırları değiştirebilir. Bu durumda, UPDATE
deyimi güncelleştirilmiş satırlarda özel kullanım kilidi istemenin yanı sıra birleştirme tablosunda okunan satırlarda paylaşılan kilitler ister.
Niyet kilitleri
Veritabanı Altyapısı, kilit hiyerarşisinde daha düşük bir kaynağa paylaşılan (S
) veya özel (X
) kilidi yerleştirmeyi korumak için amaç kilitlerini kullanır. Amaç kilitleri"amaç kilitleri" olarak adlandırılır çünkü bunlar daha düşük düzeydeki bir kilitden önce alınır ve bu nedenle kilitleri daha düşük bir düzeye yerleştirmek için sinyal amacını gösterir.
Amaç kilitleri iki amaca hizmet eder:
- Diğer işlemlerin, üst düzey kaynağı alt düzey kilidi geçersiz kılacak şekilde değiştirmesini önlemek için.
- Daha yüksek ayrıntı düzeyinde kilit çakışmalarını algılamada Veritabanı Altyapısı'nın verimliliğini artırmak için.
Örneğin, bir tablo içindeki sayfalarda veya satırlarda paylaşılan (S
) kilitler istenmeden önce, tablo düzeyinde bir paylaşılan amaç kilidi talep edilir. Amaç kilidinin tablo düzeyinde ayarlanması, başka bir işlemin daha sonra bu sayfayı içeren tabloda özel (X
) kilidi almasını önler. Veritabanı Altyapısı yalnızca tablo düzeyindeki amaç kilitlerini inceleyerek bir işlemin bu tabloda güvenli bir şekilde kilit edinip edinemediğini saptamak için amaç kilitleri performansı artırır. Bu, bir işlemin tablonun tamamını kilitleyip kilitleyemediğini belirlemek için tablodaki her satır veya sayfa kilidini inceleme gereksinimini ortadan kaldırır.
Niyet kilitleri; niyet paylaşımlı (IS
), niyet özel (IX
) ve niyet özel ile paylaşımlı (SIX
) içerir.
Kilit modu | Açıklama |
---|---|
Niyet paylaşıldı (IS ) |
Hiyerarşinin alt kısmındaki bazı (ancak tümü değil) kaynaklarda istenen veya alınan paylaşılan kilitleri korur. |
Amacı özel (IX ) |
Hiyerarşinin alt kısmındaki bazı (ancak tümü değil) kaynaklar üzerinde istenen veya alınan özel kullanım kilitlerini korur.
IX , IS üst kümesidir ve alt düzey kaynaklarda paylaşılan kilit istemeyi de korur. |
Özel amaçlı paylaşılan (SIX ) |
Hiyerarşide daha düşük olan tüm kaynaklarda istenen veya alınan paylaşılan kilitleri korur ve alt düzey kaynakların bazılarında (tümü değil) özel amaçlı kilitler. Üst düzey kaynakta eşzamanlı IS kilitlerine izin verilir. Örneğin, bir tabloda SIX kilidi almak, değiştirilen sayfalarda istek özel kilitleri ve değiştirilen satırlarda özel kilitler de alır. Bir kerede kaynak başına yalnızca bir SIX kilidi olabilir ve diğer işlemler tarafından yapılan kaynak güncelleştirmelerini önleyebilir, ancak diğer işlemler tablo düzeyinde IS kilitleri alarak hiyerarşinin alt kısmındaki kaynakları okuyabilir. |
Amaç güncellemesi (IU ) |
hiyerarşisinde daha düşük olan tüm kaynaklarda istenen veya alınan güncelleştirme kilitlerini korur.
IU kilitleri yalnızca sayfa kaynaklarında kullanılır.
IU kilitleri, güncelleştirme işlemi gerçekleşirse IX kilitlere dönüştürülür. |
Paylaşılan amaç güncelleştirmesi (SIU ) |
S ve IU kilitlerinin birleşimi, bu kilitlerin ayrı olarak alınması ve aynı anda her iki kilidin de tutulması sonucu. Örneğin, bir işlem PAGLOCK ipucuyla bir sorgu yürütür ve ardından bir güncelleştirme işlemi yürütür.
PAGLOCK ipucuna sahip sorgu S kilidini alır ve güncelleştirme işlemi IU kilidini alır. |
Güncelleştirme amacı özel (UIX ) |
U ve IX kilitlerinin birleşimi, bu kilitlerin ayrı olarak alınması ve aynı anda her iki kilidin de tutulması sonucu. |
Şema kilitleri
Veritabanı Altyapısı, tablo veri tanımı dili (DDL) işlemi sırasında sütun ekleme veya tablo bırakma gibi şema değişiklikleri (Sch-M
) kilitleri kullanır.
Sch-M
kilidi, tutulduğu süre boyunca tabloya eşzamanlı erişimi engeller. Başka bir deyişle Sch-M
kilidi, kilit serbest bırakılana kadar tüm dış işlemleri engeller.
Tablo kesme gibi bazı veri işleme dili (DML) işlemleri, eşzamanlı işlemler tarafından etkilenen tablolara erişimi önlemek için Sch-M
kilitleri kullanır.
Veritabanı Altyapısı, sorguları derlerken ve yürütürken şema kararlılığı (Sch-S
) kilitlerini kullanır.
Sch-S
kilitleri, özel (X
) kilitler dahil olmak üzere hiçbir işlem kilidini engellemez. Bu nedenle, tablodaki X
kilitleri de dahil olmak üzere diğer işlemler, bir sorgu derlenmekteyken çalışmaya devam eder. Ancak, eşzamanlı DDL işlemleri ve Sch-M
kilitleri alan eşzamanlı DML işlemleri Sch-S
kilitleri tarafından engellenir.
Toplu güncelleştirme kilitleri
Toplu güncelleştirme (BU
) kilitleri, birden çok iş parçacığının verileri aynı tabloya eşzamanlı olarak toplu olarak yüklemesine olanak sağlarken, verileri toplu yüklemeyen diğer işlemlerin tabloya erişmesini engeller. Veritabanı Altyapısı, aşağıdaki koşulların her ikisi de doğru olduğunda toplu güncelleştirme (BU
) kilitlerini kullanır.
- Transact-SQL
BULK INSERT
deyimini veyaOPENROWSET(BULK)
işlevini veya .NETSqlBulkCopy
, OLEDB Hızlı Yükleme API'leri veya ODBC Toplu Kopyalama API'leri gibi Toplu Ekleme API'leri komutlarından birini kullanarak verileri tabloya toplu olarak kopyalarsınız. -
TABLOCK
ipucu belirtilir veyatable lock on bulk load
tablo seçeneği sp_tableoptionkullanılarak ayarlanır.
Bahşiş
Daha az kısıtlayıcı bir Toplu Güncelleştirme (BU
) kilidi tutan BULK INSERT deyiminden farklı olarak, INSERT INTO...SELECT
ipucuyla TABLOCK
tabloda özel bir amaç (IX
) kilidi barındırır. Bu, paralel ekleme işlemlerini kullanarak satır ekleyemeyeceğiniz anlamına gelir.
Anahtar aralığı kilitleri
Anahtar aralığı kilitleri, SERIALIZABLE
işlem yalıtım düzeyini kullanırken Transact-SQL deyimi tarafından okunan bir kayıt kümesine örtük olarak dahil edilen satır aralığını korur. Anahtar aralığı kilitleme, hayalet okumaları önler. Satırlar arasındaki anahtar aralıklarını koruyarak, bir işlem tarafından erişilen bir kayıt kümesine hayalet ekleme veya silme işlemlerini de önler.
Uyumluluğu kilitle
Kilit uyumluluğu, birden çok işlemin aynı kaynakta aynı anda kilit alıp alamayacağını denetler. Kaynak zaten başka bir işlem tarafından kilitlenmişse, yeni bir kilit isteği yalnızca istenen kilidin modu mevcut kilidin moduyla uyumluysa verilebilir. İstenen kilidin modu mevcut kilitle uyumlu değilse, yeni kilidi isteyen işlem mevcut kilidin serbest bırakılabilmesini veya kilit zaman aşımı aralığının süresinin dolmasını bekler. Örneğin, hiçbir kilit modu özel kilitlerle uyumlu değildir. Özel (X
) bir kilit tutulsa da, özel (X
) kilidi serbest bırakılana kadar başka hiçbir işlem bu kaynakta herhangi bir tür (paylaşılan, güncelleştirme veya özel kullanım) kilidi eldeemez. Buna karşılık, bir kaynağa paylaşılan (S
) kilidi uygulanmışsa, diğer işlemler de paylaşılan bir kilit veya ilk işlem tamamlanmamış olsa bile bu kaynak üzerinde bir güncelleştirme (U
) kilidi alabilir. Ancak, paylaşılan kilit kaldırılana kadar diğer işlemler özel bir kilit elde edemez.
Aşağıdaki tabloda en sık karşılaşılan kilit modlarının uyumluluğu gösterilmektedir.
Mevcut izinli mod | IS |
S |
U |
IX |
SIX |
X |
---|---|---|---|---|---|---|
İstenen mod | ||||||
Niyet paylaşıldı (IS ) |
Evet | Evet | Evet | Evet | Evet | Hayır |
Paylaşılan (S ) |
Evet | Evet | Evet | Hayır | Hayır | Hayır |
Güncelleştirme (U ) |
Evet | Evet | Hayır | Hayır | Hayır | Hayır |
Amacı özel (IX ) |
Evet | Hayır | Hayır | Evet | Hayır | Hayır |
Özel amaçlı paylaşılan (SIX ) |
Evet | Hayır | Hayır | Hayır | Hayır | Hayır |
Özel (X ) |
Hayır | Hayır | Hayır | Hayır | Hayır | Hayır |
Not
Amaç, tüm satırlar yerine yalnızca bazı satırları güncellemek olduğu anlamına gelir ki (IX
), niyet özel (IX
) kilit, IX
kilit moduyla uyumludur. Bazı satırları okumaya veya güncelleştirmeye çalışan diğer işlemlere, diğer işlemler tarafından güncelleştirilen aynı satırlar olmadığı sürece de izin verilir. Ayrıca, iki işlem aynı satırı güncelleştirmeye çalışırsa, her iki işleme de tablo ve sayfa düzeyinde bir IX
kilidi verilir. Ancak, bir işleme satır düzeyinde bir X
kilidi verilir. Diğer işlem satır düzeyi kilidi kaldırılana kadar beklemelidir.
Veritabanı Altyapısı'nda kullanılabilen tüm kilit modlarının uyumluluğunu belirlemek için aşağıdaki tabloyu kullanın.
Kilit çakışmaları ve uyumluluk matrisini gösteren
Anahtar | Açıklama |
---|---|
N | Çakışma yok |
Ben | Yasa dışı |
C | Anlaşmazlık |
Hollanda | Kilit yok |
SCH-S | Şema kararlılığı kilidi |
SCH-M | Şema değişikliği kilidi |
S | Paylaşılan |
U | Güncelleştirmek |
X | Seçkin |
DİR | Amaç paylaşıldı |
IU | Amaç güncellemesi |
9 | Amaç münhasır kullanım |
SIU | Niyet güncellemesiyle paylaşma |
ALTI | Niyetle özel paylaşım |
UIX | Özel amaçlı güncelleme |
BU | Toplu güncelleştirme |
RS-S | Paylaşılan aralık paylaşımı |
RS-U | Paylaşılan aralık güncelleştirmesi |
RI-N | Aralık-sıfır ekle |
RI-S | Paylaşılan aralığı ekle |
RI-U | Aralık güncelleştirmesi ekleme |
RI-X | Özel aralık ekle |
RX-S | Özel olarak paylaşılan aralık |
RX-U | Özel menzil güncellemesi |
RX-X | Özel aralık için özel |
Anahtar aralığı kilitleme
Anahtar aralığı kilitleri, SERIALIZABLE
işlem yalıtım düzeyini kullanırken Transact-SQL deyimi tarafından okunan bir kayıt kümesine örtük olarak dahil edilen satır aralığını korur.
SERIALIZABLE
yalıtım düzeyi, bir işlem sırasında yürütülen tüm sorguların, işlem sırasında her yürütülürken aynı satır kümesini almasını gerektirir. Anahtar aralığı kilidi, diğer işlemlerin, anahtarların SERIALIZABLE
işlemi tarafından okunan anahtar aralığına düşeceği yeni satırları eklemesini önleyerek bu gereksinimi karşılar.
Anahtar aralığı kilitleme, hayalet okumaları önler. Satırlar arasındaki anahtar aralıklarını koruyarak, bir işlem tarafından erişilen bir kayıt kümesine hayali eklemeleri de önler.
Bir anahtar aralığı kilidi bir dizine yerleştirilir ve başlangıç ile bitiş anahtar değerleri belirtilir. Bu kilit, aralıkta yer alan anahtar değeri olan herhangi bir satırı ekleme, güncelleştirme veya silme girişimlerini engeller çünkü bu işlemlerin önce dizinde bir kilit alması gerekir. Örneğin, SERIALIZABLE
bir işlem, anahtar değerleri koşul SELECT
eşleşen tüm satırları okuyan bir BETWEEN 'AAA' AND 'CZZ'
deyimi verebilir. ' AAA' ''CZZ' aralığındaki anahtar değerleri üzerindeki anahtar aralığı kilidi, diğer işlemlerin bu aralıktaki herhangi bir yere anahtar değerleri içeren satırlar eklemesini önler. 'ADG', 'BBD'veya ' 'CAL'gibi.
Anahtar aralığı kilit modları
Anahtar aralığı kilitleri, aralık ve satır bileşenlerini aralık-satır formatında içerir.
- Aralık, ardışık iki dizin girdisi arasındaki aralığı koruyan kilit modunu temsil eder.
- Satır, dizin girişini koruyan kilit modunu temsil eder.
- Mod, kullanılan birleşik kilit modunu temsil eder. Anahtar aralığı kilit modları iki bölümden oluşur. birincisi dizin aralığını kilitlemek için kullanılan kilit türünü (AralıkT) ve ikincisi belirli bir anahtarı kilitlemek için kullanılan kilit türünü temsil eder (K). İki parça, AralıkT-Körneğinde olduğu gibi kısa çizgi (-) ile bağlanır.
Aralık | Sıra | Mod | Açıklama |
---|---|---|---|
RangeS |
S |
RangeS-S |
Paylaşılan aralık, paylaşılan kaynak kilidi; aralık taraması SERIALIZABLE . |
RangeS |
U |
RangeS-U |
Paylaşılan aralık, kaynak kilidini güncelleştirme; SERIALIZABLE güncelleştirme taraması. |
RangeI |
Null |
RangeI-N |
Aralık ekle, null kaynak kilidi; dizine yeni bir anahtar eklemeden önce aralıkları test etmek için kullanılır. |
RangeX |
X |
RangeX-X |
Özel aralık, özel kaynak kilidi; bir aralıktaki bir anahtarı güncelleştirirken kullanılır. |
Not
dahili Null
kilit modu diğer tüm kilit modlarıyla uyumludur.
Anahtar aralığı kilit modlarının hangi kilitlerin çakışan anahtarlar ve aralıklarda elde edilen diğer kilitlerle uyumlu olduğunu gösteren bir uyumluluk matrisi vardır.
Mevcut izinli mod | S |
U |
X |
RangeS-S |
RangeS-U |
RangeI-N |
RangeX-X |
---|---|---|---|---|---|---|---|
İstenen mod | |||||||
Paylaşılan (S ) |
Evet | Evet | Hayır | Evet | Evet | Evet | Hayır |
Güncelleştirme (U ) |
Evet | Hayır | Hayır | Evet | Hayır | Evet | Hayır |
Özel (X ) |
Hayır | Hayır | Hayır | Hayır | Hayır | Evet | Hayır |
RangeS-S |
Evet | Evet | Hayır | Evet | Evet | Hayır | Hayır |
RangeS-U |
Evet | Hayır | Hayır | Evet | Hayır | Hayır | Hayır |
RangeI-N |
Evet | Evet | Evet | Hayır | Hayır | Evet | Hayır |
RangeX-X |
Hayır | Hayır | Hayır | Hayır | Hayır | Hayır | Hayır |
Dönüştürme kilitleri
Bir anahtar aralığı kilidi başka bir kilitle çakıştığında dönüştürme kilitleri oluşturulur.
Kilit 1 | Kilit 2 | Dönüştürme kilidi |
---|---|---|
S |
RangeI-N |
RangeI-S |
U |
RangeI-N |
RangeI-U |
X |
RangeI-N |
RangeI-X |
RangeI-N |
RangeS-S |
RangeX-S |
RangeI-N |
RangeS-U |
RangeX-U |
Dönüştürme kilitleri, bazen eşzamanlı işlemler çalıştırılırken farklı karmaşık koşullar altında kısa bir süre gözlemlenebilir.
Serileştirilebilir aralık taraması, tek öğe alma, silme ve ekleme
Anahtar aralığı kilitleme, aşağıdaki işlemlerin seri hale getirilebilir olmasını sağlar:
- Aralık tarama sorgusu
- Mevcut olmayan satırın tek satır alma işlemi
- Silme işlemi
- Ekleme işlemi
Anahtar aralığı kilitlemenin gerçekleşebilmesi için önce aşağıdaki koşulların karşılanması gerekir:
- İşlem yalıtım düzeyi
SERIALIZABLE
olarak ayarlanmalıdır. - Sorgu işlemcisi, aralık filtresi koşulunu uygulamak için bir dizin kullanmalıdır. Örneğin,
WHERE
deyimindekiSELECT
yan tümcesi bu yargıyla bir aralık koşulu kurabilir:ColumnX BETWEEN N'AAA' AND N'CZZ'
. Anahtar aralığı kilidi yalnızcaColumnX
bir dizin anahtarı tarafından kapsanıyorsa edinilebilir.
Örnekler
Aşağıdaki tablo ve dizin, izleyen anahtar aralığı kilitleme örnekleri için temel olarak kullanılır.
Aralık tarama sorgusu
Bir aralık tarama sorgusunun serileştirilebilir olduğundan emin olmak için, aynı sorgu aynı işlem içinde her yürütülürken aynı sonuçları döndürmelidir. Diğer işlemler tarafından aralık tarama sorgusu içinde yeni satırlar eklenmemelidir; aksi takdirde, bunlar görünmez eklemeler haline gelir. Örneğin, aşağıdaki sorgu önceki çizimdeki tabloyu ve dizini kullanır:
SELECT name
FROM mytable
WHERE name BETWEEN 'A' AND 'C';
Anahtar aralığı kilitleri, adın Adam
ve Dale
değerleri arasında olduğu satır aralığına karşılık gelen dizin girişlerine yerleştirilir ve önceki sorguda nitelenen yeni satırların eklenmesini veya silinmesini önler. Bu aralıktaki ilk ad Adam
olmasına rağmen, bu dizin girdisindeki RangeS-S
modu anahtar aralığı kilidi, A
öncesinde Adam
harfiyle başlayan Abigail
gibi yeni adların eklenememesini sağlar. Benzer şekilde, RangeS-S
için dizin girdisindeki Dale
anahtar aralığı kilidi, C
gibi Carlos
'ten sonra Clive
harfiyle başlayan yeni adların eklenemeyeceğini garanti eder.
Not
Tutulan RangeS-S
kilit sayısı n+1'dir ve burada n, sorguyu karşılayan satırların sayısını belirtir.
Var olmayan verilerin tek seferlik alınması
İşlem içindeki bir sorgu var olmayan bir satır seçmeye çalışırsa, sorguyu aynı işlem içinde daha sonraki bir noktada vermenin aynı sonucu döndürmesi gerekir. Başka hiçbir işlemin var olmayan satırı eklemesine izin verilmez. Örneğin, bu sorgu göz önüne alındığında:
SELECT name
FROM mytable
WHERE name = 'Bill';
Ben
ismi bu iki bitişik dizin girdisinin arasına ekleneceği için, Bing
ile Bill
arasındaki ismi temsil eden dizin girdisine bir anahtar aralığı kilidi uygulanır.
RangeS-S
modu anahtar aralığı kilidi Bing
dizin girdisine yerleştirilir. Bu, Bill
ve Ben
dizin girdileri arasına Bing
gibi başka bir işlemin değer eklemesini önler.
İyileştirilmiş kilitleme olmadan silme işlemi
Bir işlem içindeki bir satırı silerken, satırın içine düştüğü aralığın silme işlemini gerçekleştiren işlemin süresi boyunca kilitlenmesi gerekmez. Silinen anahtar değerini işlemin sonuna kadar kilitlemek seri hale getirilebilirliği korumak için yeterlidir. Örneğin, bu DELETE
ifadesi göz önünde bulundurulduğunda:
DELETE mytable
WHERE name = 'Bob';
X
adına karşılık gelen dizin girişine özel (Bob
) bir kilit yerleştirilir. Diğer işlemler, silinmekte olan değer Bob
satırın önüne veya arkasına değer ekleyebilir veya silebilir. Ancak, Bob
değeriyle eşleşen satırları okumaya, eklemeye veya silmeye çalışan tüm işlemler, silme işlemi işleyene veya geri dönene kadar engellenir. (READ_COMMITTED_SNAPSHOT
veritabanı seçeneği ve SNAPSHOT
yalıtım düzeyi, daha önce kaydedilmiş durumun satır sürümünden okuma işlemlerine de izin verir.)
Aralık silme işlemi üç temel kilit modu kullanılarak yürütülebilir: satır, sayfa veya tablo kilidi. Satır, sayfa veya tablo kilitleme stratejisi Sorgu İyileştiricisi tarafından belirlenir veya kullanıcı tarafından ROWLOCK
, PAGLOCK
veya TABLOCK
gibi Sorgu İyileştirici ipuçlarıyla belirtilebilir.
PAGLOCK
veya TABLOCK
kullanıldığında, bu sayfadaki tüm satırlar silinirse Veritabanı Altyapısı hemen bir dizin sayfasını serbest bırakır. Buna karşılık, ROWLOCK
kullanıldığında, silinen tüm satırlar yalnızca silinmiş olarak işaretlenir; bunlar daha sonra bir arka plan görevi kullanılarak dizin sayfasından kaldırılır.
İyileştirilmiş kilitleme ile silme işlemi
Bir işlem içindeki bir satırı silerken, satır ve sayfa kilitleri artımlı olarak alınır ve serbest bırakılır ve işlem süresi boyunca tutulmaz. Örneğin, şu DELETE deyimi göz önünde bulundurulduğunda:
DELETE mytable
WHERE name = 'Bob';
TID kilidi, işlem süresi boyunca değiştirilen tüm satırlara yerleştirilir.
Bob
değerine karşılık gelen dizin satırlarının TID'si üzerinde bir kilit konur. İyileştirilmiş kilitleme ile, güncelleştirmeler için sayfa ve satır kilitleri alınmaya devam eder, ancak her satır güncelleştirildiğinde her sayfa ve satır kilidi serbest bırakılır. TID kilidi, işlem tamamlanana kadar satırların güncelleştirilmesini engeller.
Bob
değeriyle satırları okumaya, eklemeye veya silmeye çalışan tüm işlemler, silme işlemi tamamlanana veya geri alana kadar engellenir. (READ_COMMITTED_SNAPSHOT
veritabanı seçeneği ve SNAPSHOT
yalıtım düzeyi, daha önce kaydedilmiş durumun satır sürümünden okuma işlemlerine de izin verir.)
Aksi takdirde, silme işleminin kilitleme mekanizması, iyileştirilmiş kilitleme olmadan olduğu gibi aynıdır.
İyileştirilmiş kilitleme olmadan ekleme işlemi
Bir işlem içine satır eklerken, satırın içine düştüğü aralığın, ekleme işlemini gerçekleştiren işlemin süresi boyunca kilitlenmesi gerekmez. Eklenen anahtar değerini işlemin sonuna kadar kilitlemek seri hale getirilebilirliği korumak için yeterlidir. Örneğin, bu INSERT deyimi göz önünde bulundurulduğunda:
INSERT mytable VALUES ('Dan');
RangeI-N
mod anahtarı menzili kilidi, aralığı test etmek için isim David
’e karşılık gelen dizin satırına yerleştirilir. Kilit verilirse, Dan
değerine sahip bir satır eklenir ve eklenen satıra özel (X
) bir kilit yerleştirilir.
RangeI-N
modu anahtar aralığı kilidi yalnızca aralığı test etmek için gereklidir ve ekleme işlemini gerçekleştiren işlem süresi boyunca tutulmaz. Diğer işlemler, Dan
değeriyle eklenen satırdan önce veya sonra değerleri ekleyebilir veya silebilir. Ancak, Dan
değeriyle satırı okumaya, eklemeye veya silmeye çalışan herhangi bir işlem, ekleme işlemi ya tamamlanana ya da geri alınıncaya kadar engellenir.
Optimize edilmiş kilitleme ile ekleme işlemi
Bir işlem içine satır eklerken, satırın içine düştüğü aralığın, ekleme işlemini gerçekleştiren işlemin süresi boyunca kilitlenmesi gerekmez. Satır ve sayfa kilitleri nadiren, yalnızca devam eden çevrimiçi dizin yeniden oluşturma işlemi olduğunda veya eşzamanlı SERIALIZABLE
işlemleri olduğunda alınır. Satır ve sayfa kilitleri alınırsa, bunlar hızlı bir şekilde serbest bırakılır ve işlem süresi boyunca tutulmaz. Seri hale getirilebilirliği korumak için işlemin sonuna kadar eklenen anahtar değerine özel bir TID kilidi yerleştirmek yeterlidir. Örneğin, bu INSERT
ifadesi göz önünde bulundurulduğunda:
INSERT mytable VALUES ('Dan');
İyileştirilmiş kilitleme ile, bir RangeI-N
kilidi yalnızca örnekte SERIALIZABLE
yalıtım düzeyini kullanan en az bir işlem varsa alınır.
RangeI-N
mod anahtarı menzili kilidi, aralığı test etmek için isim David
’e karşılık gelen dizin satırına yerleştirilir. Kilit verilirse, Dan
değerine sahip bir satır eklenir ve eklenen satıra özel (X
) bir kilit yerleştirilir.
RangeI-N
modu anahtar aralığı kilidi yalnızca aralığı test etmek için gereklidir ve ekleme işlemini gerçekleştiren işlem süresi boyunca tutulmaz. Diğer işlemler, Dan
değeriyle eklenen satırdan önce veya sonra değerleri ekleyebilir veya silebilir. Ancak, Dan
değeriyle satırı okumaya, eklemeye veya silmeye çalışan herhangi bir işlem, ekleme işlemi ya tamamlanana ya da geri alınıncaya kadar engellenir.
İlerletme kilidini açma
Kilit yükseltmesi, çok sayıda ince taneli kilidi daha az kaba taneli kilitlere dönüştürerek sistem ek yükünü azaltırken eşzamanlılık çekişmesi olasılığını artırma işlemidir.
Kilit yükseltme, iyileştirilmiş kilitleme etkinleştirilip etkinleştirilmediğine bağlı olarak farklı davranır.
İyileştirilmiş kilitleme olmadan yükseltmeyi kilitleme
Veritabanı Motoru alt düzey kilitler aldıkça, alt düzey nesneleri içeren nesnelerde de niyet kilitleri yerleştirir.
- Veritabanı Motoru, satırları veya dizin anahtarı aralıklarını kilitlerken, satırları veya anahtarları içeren sayfalara bir niyet kilidi yerleştirir.
- Sayfaları kilitlerken, Veritabanı Altyapısı sayfaları içeren daha üst düzey nesnelere bir amaç kilidi yerleştirir. Nesnedeki amaç kilidine ek olarak, aşağıdaki nesnelerde amaç sayfası kilitleri de istenir:
- Kümelenmemiş dizinlerin yaprak düzeyi sayfaları
- Kümelenmiş dizinlerin veri sayfaları
- Yığın veri sayfaları
Veritabanı Motoru, kilit sayısını en aza indirmek ve kilit yükseltmesinin gerekli olma olasılığını azaltmak için aynı ifade için hem satır hem de sayfa kilitleme gerçekleştirebilir. Örneğin, Veritabanı Altyapısı sayfa kilitlerini kümelenmemiş bir dizine (sorguyu karşılamak için dizin düğümünde yeterli bitişik anahtar seçilirse) ve kümelenmiş dizine veya yığına satır kilitleri yerleştirebilir.
Veritabanı Altyapısı, kilitleri ilerletmek için tablodaki amaç kilidini ilgili tam kilit olarak değiştirmeyi dener; örneğin, özel amaçlı (IX
) kilidi özel (X
) kilidine veya paylaşılan bir amaç (IS
) kilidi paylaşılan (S
) kilidine değiştirmeye çalışır. Kilit yükseltme girişimi başarılı olursa ve tam tablo kilidi alınırsa, işlem tarafından yığın veya dizinde tutulan HoBT, sayfa (PAGE
) veya satır düzeyi (RID
, KEY
) kilitlerinin tümü serbest bırakılır. Tam kilit alınamazsa, o sırada kilit yükseltmesi gerçekleşmez ve Veritabanı Altyapısı satır, anahtar veya sayfa kilitlerini almaya devam eder.
Veritabanı Altyapısı satır veya anahtar aralığı kilitlerini sayfa kilitlerine yükseltmez, ancak bunları doğrudan tablo kilitlerine iletir. Benzer şekilde, sayfa kilitleri her zaman tablo kilitlerine yükseltilir. Bölümlenmiş tabloların kilitlenmesi, tablo kilidi yerine ilişkili bölüm için HoBT düzeyine yükseltilebilir. HoBT düzeyinde kilit, bölüm için hizalanmış HoBT'leri kilitlemek zorunda değildir.
Not
HoBT düzeyi kilitler genellikle eşzamanlılığı artırır, ancak her biri farklı bölümleri kilitleyen işlemler özel kilitlerini diğer bölümlere genişletmek istediğinde kilitlenme olasılığına neden olur. Nadir durumlarda, TABLE
kilitleme derecesi daha iyi performans gösterebilir.
Eşzamanlı işlemler tarafından tutulan çakışan kilitler nedeniyle kilit yükseltme girişimi başarısız olursa, Veritabanı Altyapısı işlem tarafından alınan her ek 1.250 kilit için kilit yükseltmeyi yeniden dener.
Her yükseltme olayı öncelikli olarak tek bir Transact-SQL deyimi düzeyinde çalışır. Olay başladığında Veritabanı Altyapısı, yükseltme eşiği gereksinimlerini karşılaması koşuluyla aktif ifade tarafından atıfta bulunulan tablolardan herhangi birinde, şu anki işleme ait tüm kilitleri yükseltmeye çalışır. Eğer ilerletme olayı, deyim bir tabloya erişmeden önce başlatılırsa, bu tablodaki kilitleri yükseltme girişiminde bulunulmaz. Kilit yükseltmesi başarılı olursa, önceki bir deyimde işlem tarafından alınmış ve olay başladığında hala elde tutulan tüm kilitler, tablo mevcut deyimde referans alınıyorsa ve yükseltme olayına dahil edildiyse yükseltilir.
Örneğin, bir oturumun şu işlemleri gerçekleştirdiğini varsayalım:
- bir işlem başlatır.
- Güncellemeler
TableA
. Bu, işlem tamamlanana kadar tutulanTableA
'da özel satır kilitleri oluşturur. - Güncellemeler
TableB
. Bu, işlem tamamlanana kadar tutulanTableB
'da özel satır kilitleri oluşturur. -
SELECT
ileTableA
'yi birleştiren birTableC
gerçekleştirir. Sorgu yürütme planı, satırlarınTableA
'den alınmasından önceTableC
'den alınmasını öngörüyor. -
SELECT
deyimi,TableA
'den satır alırken veTableC
'ye erişmeden önce kilit yükseltmeyi tetikler.
Kilit yükseltme başarılı olursa, yalnızca TableA
oturumu tarafından tutulan kilitler yükseltilir. Buna hem SELECT
deyiminden paylaşılan kilitler hem de önceki UPDATE
deyiminden özel kilitler dahildir. Yalnızca TableA
ifadesi için SELECT
tarafından edinilen oturum kilitleri, kilit yükseltmesinin yapılıp yapılmayacağını belirlemek için sayılır, ancak yükseltme başarıldığında, oturum tarafından TableA
üzerinde tutulan tüm kilitler tablodaki özel kilit seviyesine yükseltilir ve TableA
üzerindeki niyet kilitleri de dahil olmak üzere diğer tüm daha düşük ayrıntılı kilitler serbest bırakılır.
TableB
ifadesinde TableB
'e etkin bir başvuru olmadığı için SELECT
kilitlerini yükseltme girişiminde bulunulmuyor. Benzer şekilde, TableC
üzerinde kilitleri yükseltme girişiminde bulunulmamıştır. Bu, yükseltme gerçekleştiğinde henüz erişilmediğinden ilerletilmemiştir.
İyileştirilmiş kilitleme ile yükseltmeyi kilitleme
İyileştirilmiş kilitleme, işlem süresi boyunca çok az sayıda kilit tutulduktan sonra kilit belleğinin azaltılmasına yardımcı olur. Veritabanı Motoru satır ve sayfa kilitlerini aldıkça, kilit yükseltmesi benzer şekilde, ancak çok daha seyrek gerçekleşebilir. İyileştirilmiş kilitleme genellikle kilit yükseltmelerini önlemede başarılı olur ve kilit sayısını ve gerekli kilit belleği miktarını düşürür.
İyileştirilmiş kilitleme etkinleştirildiğinde ve varsayılan READ COMMITTED
yalıtım düzeyinde, Veritabanı Motoru satır değiştirildiğinde satır ve sayfa kilitlerini serbest bırakır. Tek bir İşlem Kimliği (TID) kilidi dışında işlem süresi boyunca hiçbir satır ve sayfa kilidi tutulmaz. Bu, kilit artışı olasılığını azaltır.
İlerletme eşiklerini kilitleme
ALTER TABLE SET LOCK_ESCALATION
seçeneği kullanılarak tabloda kilit yükseltme devre dışı bırakılmadığında ve aşağıdaki koşullardan biri mevcut olduğunda kilit yükseltme tetikleniyor:
- Tek bir Transact-SQL deyimi, bölümlere ayrılmamış tek bir tablo veya dizin üzerinde en az 5.000 kilit edinir.
- Tek bir Transact-SQL deyimi bölümlenmiş tablonun tek bir bölümünde en az 5.000 kilit alır ve
ALTER TABLE SET LOCK_ESCALATION
seçeneği AUTO olarak ayarlanır. - Veritabanı Altyapısı örneğindeki kilit sayısı bellek veya yapılandırma eşiklerini aşıyor.
Kilit çakışmaları nedeniyle kilitler yükseltilemiyorsa, Veritabanı Altyapısı alınan her 1.250 yeni kilitte düzenli aralıklarla kilit yükseltmeyi tetikler.
Transact-SQL deyimi için yükseltme eşiği
Veritabanı Altyapısı, yeni alınan her 1.250 kilitte olası yükseltmeleri denetlediğinde, bir kilit yükseltmesi ancak ve ancak bir Transact-SQL ifadesi bir tablonun tek bir başvurusunda en az 5.000 kilit almışsa gerçekleşir. Bir Transact-SQL deyimi, bir tablonun tek bir referansında en az 5.000 kilit aldığı zaman kilit yükseltmesi tetiklenir. Örneğin, bir ifade bir dizinde 3.000 kilit ve aynı tablonun başka bir dizininde 3.000 kilit alırsa kilit yükseltme tetiklenmez. Benzer şekilde, bir SQL ifadesinin tabloda kendi kendine join'i varsa ve tabloda her başvuru yalnızca 3.000 kilit alıyorsa, kilit yükseltmesi tetiklenmez.
Kilit yükseltmesi yalnızca yükseltme tetiklendiğinde erişilen tablolar için gerçekleşir. Tek bir SELECT
deyiminin bu dizideki üç tabloya erişen bir birleşim olduğunu varsayalım: TableA
, TableB
ve TableC
. Açıklama, TableA
için kümelenmiş dizinde 3.000 satır kilidi ve TableB
için kümelenmiş dizinde en az 5.000 satır kilidi alır, ancak henüz TableC
'ye erişmemiştir. Veritabanı Motoru ifadenin TableB
içinde en az 5.000 satır kilidi aldığını tespit ettiğinde, TableB
üzerinde geçerli işlem tarafından tutulan tüm kilitleri yükseltmeye çalışır. Ayrıca, TableA
üzerinde geçerli işlem tarafından tutulan tüm kilitleri yükseltmeye çalışır, ancak TableA
üzerindeki kilit sayısı 5.000'den az olduğundan, yükseltme başarılı olmaz.
TableC
için herhangi bir kilit yükseltme girişiminde bulunulamamıştır çünkü yükseltme gerçekleştiğinde henüz erişilmemiştir.
Veritabanı Altyapısı örneği için yükseltme eşiği
Kilit sayısı, kilit yükseltme için bellek eşiğinden büyük olduğunda, Veritabanı Altyapısı kilit yükseltmesini tetikler. Bellek eşiği, yapılandırma seçeneğinin ayarına bağlıdır:
locks
seçeneği varsayılan 0 ayarına ayarlanırsa, kilit nesneleri tarafından kullanılan bellek Veritabanı Altyapısı tarafından kullanılan belleğin yüzde 24'ü (AWE belleği hariç) olduğunda kilit yükseltme eşiğine ulaşılır. Bir kilidi temsil etmek için kullanılan veri yapısı yaklaşık 100 bayt uzunluğundadır. Bu eşik dinamiktir çünkü Veritabanı Altyapısı değişen iş yüklerine uyum sağlamak için belleği dinamik olarak alır ve boşaltır.locks
seçeneği 0 dışında bir değerse kilit yükseltme eşiği, kilitler seçeneğinin değerinin yüzde 40'ıdır (veya bellek baskısı varsa daha azdır).
Veritabanı Altyapısı yükseltme için herhangi bir oturumdan herhangi bir etkin deyimi seçebilir ve örnekte kullanılan kilit belleği eşiğin üzerinde kaldığı sürece her 1.250 yeni kilit için yükseltme deyimlerini seçer.
Karma kilit türleriyle kilit yükseltme
Kilit yükseltme gerçekleştiğinde, yığın veya dizin için seçilen kilit, en kısıtlayıcı alt düzey kilidin gereksinimlerini karşılayacak kadar güçlüdür.
Örneğin, bir oturum olduğunu varsayalım:
- bir işlem başlatır.
- Kümelenmiş dizin içeren bir tabloyu güncelleştirir.
- Aynı tabloya başvuran bir
SELECT
deyimi oluşturur.
UPDATE
deyimi şu kilitleri edinir:
- Güncellenmiş veri satırlarına özel kilitler (
X
). - Intent exclusive (
IX
), bu satırları içeren kümelenmiş dizin sayfalarına kilitler. - Kümelenmiş dizinde bir
IX
kilidi ve tabloda başka bir kilit bulunmakta.
SELECT
deyimi şu kilitleri edinir:
- Paylaşılan (
S
) kilitler, satır zatenX
deyiminden birUPDATE
kilidiyle korunmuş değilse okuduğu tüm veri satırlarına uygulanır. - Intent Shared (
IS
), sayfa zaten birIX
kilidiyle korunuyorsa hariç olmak üzere, bu satırları içeren tüm kümelenmiş dizin sayfalarında kilitler uygular. - Küme dizininde veya tabloda kilit yoktur, çünkü zaten
IX
kilitler tarafından korunmaktadır.
SELECT
deyimi, kilit yükseltmeyi tetikleyebilmek için yeterli kilit alırsa ve yükseltme başarılı olursa, tablodaki IX
kilidi X
kilidine dönüştürülür ve tüm satır, sayfa ve dizin kilitleri serbest bırakılır. Hem güncelleştirmeler hem de okumalar, tablodaki X
kilidi tarafından korunur.
Kilitlemeyi ve kilit yükseltmeyi azaltma
Çoğu durumda Veritabanı Altyapısı, kilit ve kilit yükseltme için varsayılan ayarlarıyla çalışırken en iyi performansı sunar.
için optimize edilmişkilitlemesinden yararlanın.
- İyileştirilmiş kilitleme, kilit bellek tüketimini azaltan ve eşzamanlı işlemler için engellemeyi azaltan geliştirilmiş bir işlem kilitleme mekanizması sunar. İyileştirilmiş kilitleme etkinleştirildiğinde kilit yükseltmenin gerçekleşme olasılığı çok daha düşüktür.
- ile iyileştirilmiş kilitleme kullanıldığındatablo ipuçlarını kullanmaktan kaçının. Tablo ipuçları, iyileştirilmiş kilitlemenin verimliliğini azaltabilir.
- İyileştirilmiş kilitlemeden en iyi şekilde yararlanmak için veritabanı için READ_COMMITTED_SNAPSHOT seçeneğini etkinleştirin. Bu, Azure SQL Veritabanı'nda varsayılan değerdir.
- İyileştirilmiş kilitleme, hızlandırılmış veritabanı kurtarma (ADR) veritabanında etkinleştirilmesini gerektirir.
Veritabanı Altyapısı'nın bir örneği çok fazla kilit oluşturuyorsa ve sık sık kilit yükseltmeleri görüyorsa, aşağıdaki stratejilerle kilitleme miktarını azaltmayı göz önünde bulundurun:
Okuma işlemleri için paylaşılan kilitler oluşturmayan bir yalıtım düzeyi kullanın:
-
READ COMMITTED
veritabanı seçeneğiREAD_COMMITTED_SNAPSHOT
olduğunda yalıtım düzeyiON
. -
SNAPSHOT
yalıtım düzeyi. -
READ UNCOMMITTED
yalıtım düzeyi. Bu yalnızca kirli okumalarla çalışabilen sistemler için kullanılabilir.
-
Veritabanı Altyapısı'nın alt düzey kilitler yerine sayfa, yığın veya dizin kilitleri kullanmasını sağlamak için
PAGLOCK
veyaTABLOCK
tablo ipuçlarını kullanın. Ancak bu seçeneğin kullanılması, kullanıcıların aynı verilere erişmeye çalışan diğer kullanıcıları engelleyen sorunlarını artırır ve birkaç eşzamanlı kullanıcıya sahip sistemlerde kullanılmamalıdır.İyileştirilmiş kilitleme kullanılamıyorsa, bölümlenmiş tablolar için kilitleri tablo yerine bölüme ilerletmek veya tablonun kilitlenmesini devre dışı bırakmak için ALTER TABLE
LOCK_ESCALATION
seçeneğini kullanın.Büyük toplu işlemleri birkaç küçük işlem olarak ayırın. Örneğin, bir denetim tablosundan birkaç yüz bin eski satırı kaldırmak için aşağıdaki sorguyu çalıştırdığınızı ve ardından bunun diğer kullanıcıları engelleyen bir kilit yükseltmesine neden olduğunu bulduğunuzu varsayalım:
DELETE FROM LogMessages WHERE LogDate < '2024-09-26'
Bu satırları bir kerede birkaç yüz kaldırarak, işlem başına biriken kilit sayısını önemli ölçüde azaltabilir ve kilit yükseltmesini önleyebilirsiniz. Örneğin:
DECLARE @DeletedRows int; WHILE @DeletedRows IS NULL OR @DeletedRows > 0 BEGIN DELETE TOP (500) FROM LogMessages WHERE LogDate < '2024-09-26' SELECT @DeletedRows = @@ROWCOUNT; END;
Sorguyu mümkün olduğunca verimli hale getirerek sorgu kilidi ayak izini azaltın. Büyük taramalar veya çok sayıda anahtar araması, kilit yükseltme olasılığını artırabilir; ayrıca, bu da kilitlenme olasılığını artırır ve genellikle eşzamanlılığı ve performansı olumsuz etkiler. Kilit yükseltmesine neden olan sorguyu bulduklarından sonra, tam dizin veya tablo taramalarını kaldırmak ve dizin aramalarının verimliliğini en üst düzeye çıkarmak için yeni dizinler oluşturma veya var olan bir dizine sütun ekleme fırsatlarını arayın. Sorguda otomatik dizin analizi gerçekleştirmek için Veritabanı Altyapısı Ayarlama Danışmanı kullanmayı göz önünde bulundurun. Daha fazla bilgi için bkz. Kılavuz: Veritabanı Motoru Ayarlama Danışmanı. Bu iyileştirmenin bir hedefi, anahtar aramalarının maliyetini en aza indirmek için dizin aramalarının mümkün olduğunca az satır döndürmesini sağlamaktır (belirli bir sorgu için dizinin seçiciliğini en üst düzeye çıkarmak). Veritabanı Altyapısı bir anahtar arama mantıksal işlecinin birçok satır döndürebileceğini tahmin ederse, aramayı gerçekleştirmek için bir ön iyileştirme kullanabilir. Veritabanı Altyapısı arama için ön koşul kullanırsa, sorgunun bir bölümünün işlem yalıtım düzeyini
REPEATABLE READ
olarak artırması gerekir. Bu, şu anlama gelir ki,SELECT
yalıtım düzeyindeki birREAD COMMITTED
ifadesine benzeyen durum, binlerce anahtar kilidi (hem kümelenmiş dizinde hem de bir kümelenmemiş dizinde) edinebilir ve bu da böyle bir sorgunun kilit genişletme eşiklerini aşmasına yol açabilir. Özellikle, yükseltilen kilidin paylaşılan bir tablo kilidi olduğunu fark ederseniz bu durum önemlidir; ancak bu tür kilitler varsayılanREAD COMMITTED
yalıtım düzeyinde yaygın olarak karşılaşılmaz.Ön getirme optimizasyonuna sahip bir anahtar araması kilit yükseltmesine neden oluyorsa, sorgu planında anahtar arama mantıksal işlecinin altında yer alan Dizin Araması veya Dizin Taraması mantıksal işlecinde görünen kümelenmemiş dizine ek sütunlar eklemeyi düşünebilirsiniz.
WHERE
sütun listesindeki her şeyi dahil etmek pratik değilse, bir kapsama dizini (sorguda kullanılan bir tablodaki tüm sütunları içeren bir dizin) veya birleştirme ölçütleri için veyaSELECT
yan tümcesinde kullanılan sütunları kapsayan bir dizin oluşturmak mümkün olabilir. İç İçe Döngü birleştirmesi ön getirme optimizasyonunu da kullanabilir ve bu da aynı kilitleme davranışına neden olur.Farklı bir SPID şu anda uyumsuz bir tablo kilidi tutuyorsa kilit yükseltmesi gerçekleşemez. Kilit yükseltmesi her zaman bir tablo kilidine yükselir ve asla sayfa kilitlerine yükselmez. Ayrıca, başka bir SPID uyumsuz bir tablo kilidi tuttuğundan kilit yükseltme girişimi başarısız olursa, yükseltme girişiminde bulunan sorgu tablo kilidi beklerken engellenmez. Bunun yerine, kilitleri özgün, daha ince ayrıntı düzeyinde (satır, anahtar veya sayfa) almaya devam eder ve belirli aralıklarla ek yükseltme girişimlerinde bulunur. Bu nedenle, belirli bir tabloda kilit yükseltmesini önlemenin bir yöntemi, yükseltilmiş kilit türüyle uyumlu olmayan farklı bir bağlantı üzerinde kilit almak ve tutmaktır. Tablo düzeyinde özel amaçlı (
IX
) kilidi hiçbir satırı veya sayfayı kilitlemez, ancak yine de yükseltilmiş paylaşılan (S
) veya özel (X
) tablo kilidiyle uyumlu değildir. Örneğin,mytable
tablosundaki çok sayıda satırı değiştiren ve kilit artırılması nedeniyle engellemeye neden olmuş olan bir toplu iş (batch job) çalıştırmanız gerektiğini varsayalım. Bu iş her zaman bir saatten kısa sürede tamamlanırsa, aşağıdaki kodu içeren bir Transact-SQL işi oluşturabilir ve yeni işi toplu işin başlangıç saatinden birkaç dakika önce başlayacak şekilde zamanlayabilirsiniz:BEGIN TRAN; SELECT * FROM mytable WITH (UPDLOCK, HOLDLOCK) WHERE 1 = 0; WAITFOR DELAY '1:00:00'; COMMIT TRAN;
Bu sorgu, bir saat boyunca
IX
üzerinde birmytable
kilidi elde eder ve tutar, bu da söz konusu süre boyunca tablodaki kilit yükseltmesini önler. Bu toplu işlem hiçbir veriyi değiştirmez veya diğer sorguları engellemez (diğer sorguTABLOCK
ipucuyla bir tablo kilidini zorlamadığı veya yöneticininmytable
dizinindeki bir dizinde sayfa veya satır kilitlerini devre dışı bırakmadığı sürece).Ayrıca, kilit yükseltmelerinin tamamını veya bir kısmını devre dışı bırakmak için 1211 ve 1224 izleme bayraklarını kullanabilirsiniz. Ancak, bu izleme bayrakları veritabanı motoru örneğinin tamamı için tüm kilit yükseltmesini küresel olarak devre dışı bırakır. Kilit yükseltmesi, veritabanı motorunda, aksi takdirde birkaç bin kilidin alınması ve bırakılması ihtiyacıyla yavaşlayan sorguların verimliliğini en üst düzeye çıkararak yararlı bir amaca hizmet eder. Kilit yükseltme, kilitleri izlemek için gerekli belleğin en aza indirilmesine de yardımcı olur. Veritabanı Altyapısı'nın kilit yapıları için dinamik olarak ayırabileceği bellek sonlu olduğundan, kilit yükseltmesini devre dışı bırakırsanız ve kilit belleği yeterince büyürse, herhangi bir sorgu için ek kilit ayırma girişimleri başarısız olabilir ve aşağıdaki hata oluşur:
Error: 1204, Severity: 19, State: 1 The SQL Server cannot obtain a LOCK resource at this time. Rerun your statement when there are fewer active users or ask the system administrator to check the SQL Server lock and memory configuration.
Not
MSSQLSERVER_1204 hatası oluştuğunda geçerli deyimin işlenmesini durdurur ve etkin işlemin geri alınmasına neden olur. Veritabanı hizmetini yeniden başlatırsanız geri alma işlemi kullanıcıları engelleyebilir veya uzun bir veritabanı kurtarma süresine yol açabilir.
Not
ROWLOCK
gibi bir kilit tüyosu kullanmak yalnızca ilk kilit edinimini değiştirir. Kilit ipuçları, kilit yükseltmesini engellemez.
SQL Server 2008 (10.0.x) ile başlayarak, LOCK_ESCALATION
tablo seçeneğinin kullanıma sunulmasıyla kilit yükseltme davranışı değişti. Daha fazla bilgi için ALTER TABLE LOCK_ESCALATION
seçeneğine bakın.
Kilit yükseltmesini izleme
Kilit yükseltmesini izlemek için, aşağıdaki örnekte olduğu gibi lock_escalation
genişletilmiş olayını kullanın:
-- Session creates a histogram of the number of lock escalations per database
CREATE EVENT SESSION [Track_lock_escalation] ON SERVER
ADD EVENT sqlserver.lock_escalation
(
SET collect_database_name=1,collect_statement=1
ACTION(sqlserver.database_id,sqlserver.database_name,sqlserver.query_hash_signed,sqlserver.query_plan_hash_signed,sqlserver.sql_text,sqlserver.username)
)
ADD TARGET package0.histogram
(
SET source=N'sqlserver.database_id'
)
GO
Dinamik kilitleme
Satır kilitleri gibi düşük düzeyli kilitlerin kullanılması, iki işlemin aynı anda aynı veri parçasına kilitlenme olasılığını azaltarak eşzamanlılığı artırır. Düşük düzeyli kilitlerin kullanılması, kilit sayısını ve bunları yönetmek için gereken kaynakları da artırır. Üst düzey tablo veya sayfa kilitlerinin kullanılması ek yükü azaltır, ancak eşzamanlılığı azaltmaya neden olur.
Veritabanı Altyapısı, en etkili kilitleri belirlemek için dinamik bir kilitleme stratejisi kullanır. Veritabanı Altyapısı, şema ve sorgunun özelliklerine göre sorgu yürütülürken en uygun kilitleri otomatik olarak belirler. Örneğin, kilitleme ek yükünü azaltmak için iyileştirici dizin taraması yaparken dizindeki sayfa kilitlerini seçebilir.
Bölümleyi kilitleme
Büyük bilgisayar sistemlerinde, sıkça başvurulan nesnelerin kilitleri, kilitlerin alınması ve bırakılması iç kaynaklar üzerinde çekişmeye neden olarak performans darboğazına yol açabilir. Kilit bölümleme, tek bir kilit kaynağını birden çok kilit kaynağına bölerek kilitleme performansını artırır. Bu özellik yalnızca 16 veya daha fazla mantıksal CPU'ya sahip sistemlerde kullanılabilir ve otomatik olarak etkinleştirilir ve devre dışı bırakılamaz. Yalnızca nesne kilitleri bölümlenebilir. Alt türü olan nesne kilitleri bölümlenmez. Daha fazla bilgi için bkz. sys.dm_tran_locks (Transact-SQL).
Kilit bölümlemeyi anlama
Kilitleme görevleri, kilit bölümlendirmesiyle iyileştirilen iki tanesi dahil olmak üzere, çeşitli ortak kullanılan kaynaklara erişiyor.
Spinlock
Bu, satır veya tablo gibi bir kilit kaynağına erişimi denetler.
Kilit bölümleme olmadan, bir spinlock tek bir kilit kaynağı için tüm kilit isteklerini yönetir. Yüksek etkinlik hacmine sahip sistemlerde, kilit istekleri spinlock'un kullanılabilir hale gelmesini beklerken çekişme oluşabilir. Bu durum altında, kilit edinimi bir darboğaza dönüşebilir ve performansı olumsuz etkileyebilir.
Tek bir kilit kaynağındaki çekişme oranını azaltmak için, kilit bölümleme tek bir kilit kaynağını birden çok kilit kaynağına bölerek yükü birden çok spinlock'a dağıtır.
Bellek
Bu, kilit kaynak yapılarını saklamak için kullanılır.
Spinlock alındıktan sonra kilit yapıları bellekte depolanır ve sonra erişilir ve büyük olasılıkla değiştirilir. Kilit erişiminin birden çok kaynağa dağıtılması, CPU'lar arasında bellek bloklarını aktarma gereksinimini ortadan kaldırmaya yardımcı olur ve bu da performansın geliştirilmesine yardımcı olur.
Kilit bölümlemeyi uygulamak ve izlemek
Kilit bölümleme, 16 veya daha fazla CPU'ya sahip sistemler için varsayılan olarak açıktır. Kilit bölümleme etkinleştirildiğinde, SQL Server hata günlüğüne bilgilendiren bir ileti kaydedilir.
Bölümlenmiş bir kaynakta kilitleri edinirken:
Tek bir bölümde yalnızca
NL
,Sch-S
,IS
,IU
veIX
kilit modları alınır.Shared (
S
), exclusive (X
) veNL
,Sch-S
,IS
,IU
veIX
dışındaki modlardaki diğer kilitler, bölüm kimliği 0 ile başlayan ve bölüm kimliği sırasına göre izleyen tüm bölümlerde alınmalıdır. Bölümlenmiş bir kaynaktaki bu kilitler, bölümlenmemiş bir kaynakta aynı modda bulunan kilitlerden daha fazla bellek kullanır çünkü her bölüm etkili bir şekilde ayrı bir kilittir. Bellek artışı, bölüm sayısına göre belirlenir. SQL Server kilit performans sayaçları, bölümlenmiş ve bölümlenmemiş kilitler tarafından kullanılan bellek hakkındaki bilgileri görüntüler.
Bir işlem, başladığında bir bölüme atanır. İşlem için bölümlenebilen tüm kilit istekleri, bu işleme atanan bölümü kullanır. Bu yöntemle, farklı işlemler tarafından aynı nesnenin kaynaklarını kilitleme erişimi farklı bölümlere dağıtılır.
resource_lock_partition
Dinamik Yönetim Görünümü'ndeki sys.dm_tran_locks
sütunu, kilit bölümlenmiş kaynağın kilit bölüm kimliğini sağlar. Daha fazla bilgi için bkz. sys.dm_tran_locks (Transact-SQL).
Kilit bölümleme ile çalışma
Aşağıdaki kod örneklerde kilit bölümleme gösterilmektedir. Örneklerde, 16 CPU'ya sahip bir bilgisayar sisteminde kilit bölümleme davranışını göstermek için iki farklı oturumda iki işlem yürütülür.
Bu Transact-SQL deyimleri, aşağıdaki örneklerde kullanılan test nesnelerini oluşturur.
-- Create a test table.
CREATE TABLE TestTable
(
col1 int
);
GO
-- Create a clustered index on the table.
CREATE CLUSTERED INDEX ci_TestTable ON TestTable (col1);
GO
-- Populate the table.
INSERT INTO TestTable
VALUES (1);
GO
Örnek A
Oturum 1:
Bir SELECT
ifadesi bir işlem altında yürütülür.
HOLDLOCK
kilitleme ipucu nedeniyle, bu ifade tablodaki bir Niyetlenilmiş Paylaşımlı (IS
) kilidini alır ve korur; bu çizim için satır ve sayfa kilitleri yoksayılır.
IS
kilidi yalnızca işleme tahsis edilen bölümde alınır. Bu örnekte, IS
kilidinin bölüm kimliği 7'de alındığı varsayılır.
-- Start a transaction.
BEGIN TRANSACTION;
-- This SELECT statement will acquire an IS lock on the table.
SELECT col1
FROM TestTable
WITH (HOLDLOCK);
Oturum 2:
Bir işlem başlatılır ve işlem sırasında çalıştırılan SELECT
deyimi tablo üstünde paylaşılan (S
) kilidi alır ve korur.
S
kilidi, tüm bölümlerde alınır ve bu da her bölüm için bir tane olan birden çok tablo kilidine neden olur. Örneğin, 16 CPU'lu bir sistemde, 0-15 arası kilit bölümü kimliklerinde 16 adet S
kilidi verilecektir.
S
kilidi, oturum 1'deki işlem tarafından bölüm kimliği 7'de tutulan IS
kilidiyle uyumlu olduğundan, işlemler arasında engelleme yoktur.
BEGIN TRANSACTION;
SELECT col1
FROM TestTable
WITH (TABLOCK, HOLDLOCK);
Oturum 1:
Aşağıdaki SELECT
deyimi, oturum 1 altında hala etkin olan işlem altında yürütülür. Özel (X
) tablo kilitleme ipucu nedeniyle, işlem tabloda bir X
kilidi almaya çalışır. Ancak, 2. oturumda işlem tarafından tutulan S
kilidi, bölüm ID'si 0'da X
kilidine engel olur.
SELECT col1
FROM TestTable
WITH (TABLOCKX);
Örnek B
Oturum 1:
Bir SELECT
ifadesi bir işlem altında yürütülür.
HOLDLOCK
kilitleme ipucu nedeniyle, bu ifade tablodaki bir Niyetlenilmiş Paylaşımlı (IS
) kilidini alır ve korur; bu çizim için satır ve sayfa kilitleri yoksayılır.
IS
kilidi yalnızca işleme tahsis edilen bölümde alınır. Bu örnekte, IS
kilidinin bölüm kimliği 6'da alındığı varsayılır.
-- Start a transaction.
BEGIN TRANSACTION;
-- This SELECT statement will acquire an IS lock on the table.
SELECT col1
FROM TestTable
WITH (HOLDLOCK);
Oturum 2:
Bir SELECT
ifadesi bir işlem altında yürütülür.
TABLOCKX
kilit ipucu nedeniyle, işlem tabloda özel bir (X
) kilit almaya çalışır.
X
kilidinin bölüm kimliği 0 ile başlayan tüm bölümlerde alınması gerektiğini unutmayın.
X
kilidi, 0'dan 5'e kadar tüm bölüm kimliklerinde edinilir, ancak 6 numaralı bölüm kimliğinde edinilen IS
kilidi tarafından engellenir.
X
kilidinin henüz erişmediği 7-15 bölüm kimliklerinde, diğer işlemler kilit almaya devam edebilir.
BEGIN TRANSACTION;
SELECT col1
FROM TestTable
WITH (TABLOCKX, HOLDLOCK);
Veritabanı Altyapısı'nda satır sürüm oluşturma tabanlı yalıtım düzeyleri
SQL Server 2005 (9.x) sürümünden başlayarak Veritabanı Altyapısı, satır sürümü kullanarak sorgu düzeyinde anlık görüntü sağlayan READ COMMITTED
mevcut işlem yalıtım düzeyinin bir uygulamasını sunar. Veritabanı Motoru, SNAPSHOT
, satır sürümleme kullanarak bir işlem düzeyi anlık görüntüsü sağlayabilen bir işlem yalıtım düzeyi de sunar.
Satır sürümü oluşturma, SQL Server'da bir satır değiştirildiğinde veya silindiğinde yazmada kopyalama mekanizmasını çağıran genel bir çerçevedir. Bu işlem çalışırken, işlem açısından tutarlı önceki bir durum gerektiren işlemler için satırın eski sürümünün kullanılabilir olması gerekir. Satır sürümü oluşturma, aşağıdaki özellikleri uygulamak için kullanılır:
- tetikleyicilerde
inserted
vedeleted
tabloları oluşturun. Tetikleyici tarafından değiştirilen tüm satırlar için sürüm oluşturulur. Bu, tetikleyiciyi başlatan deyimi tarafından değiştirilen satırların yanı sıra tetikleyici tarafından yapılan veri değişikliklerini içerir. - Birden çok Etkin Sonuç Kümesini (MARS) destekleme. Bir MARS oturumu, etkin bir sonuç kümesi olduğunda bir veri değişiklik deyimi (
INSERT
,UPDATE
veyaDELETE
gibi) gönderirse, değişiklik deyiminden etkilenen satırlar versiyonlanır. -
ONLINE
seçeneğini belirten dizin işlemlerini destekleyin. - Satır sürümleme tabanlı işlem yalıtım düzeylerini destekleme:
- Deyim düzeyinde okuma tutarlılığı sağlamak için satır sürümlemesi kullanan
READ COMMITTED
yalıtım düzeyinin yeni uygulaması. - İşlem düzeyi okuma tutarlılığı sağlamak için
SNAPSHOT
yeni bir yalıtım düzeyi.
- Deyim düzeyinde okuma tutarlılığı sağlamak için satır sürümlemesi kullanan
Satır sürümleri bir sürüm deposunda depolanır.
hızlandırılmış veritabanı kurtarma (ADR) bir veritabanında etkinleştirilirse, sürüm deposu bu veritabanında oluşturulur. Aksi takdirde, sürüm deposu tempdb
veritabanında oluşturulur.
Veritabanı sürüm deposu için yeterli alana sahip olmalıdır. Sürüm deposu tempdb
olduğunda ve tempdb
veritabanı dolduğunda, güncelleştirme işlemleri sürümleri oluşturmayı durdurur, ancak başarılı bir şekilde devam eder, ancak gereken belirli bir satır sürümü mevcut olmadığından okuma işlemleri başarısız olabilir. Bu, tetikleyiciler, MARS ve çevrimiçi dizin oluşturma gibi işlemleri etkiler.
ADR kullanıldığında ve sürüm deposu dolu olduğunda okuma işlemleri başarılı olur ancak UPDATE
ve DELETE
gibi sürümleri oluşturan yazma işlemleri başarısız olur. Veritabanında yeterli alan varsa INSERT
işlemleri başarılı olur.
READ COMMITTED
ve SNAPSHOT
işlemleri için satır sürümü oluşturmanın kullanılması iki adımlı bir işlemdir:
READ_COMMITTED_SNAPSHOT
veALLOW_SNAPSHOT_ISOLATION
veritabanı seçenekleriniON
olarak ayarlayın.Bir uygulamada uygun işlem yalıtım düzeyini ayarlayın:
-
READ_COMMITTED_SNAPSHOT
veritabanı seçeneğiON
olduğunda,READ COMMITTED
yalıtım düzeyini ayarlayan işlemler satır sürümü kullanır. -
ALLOW_SNAPSHOT_ISOLATION
veritabanı seçeneğiON
olduğunda, işlemlerSNAPSHOT
yalıtım düzeyini ayarlayabilir.
-
READ_COMMITTED_SNAPSHOT
veya ALLOW_SNAPSHOT_ISOLATION
veritabanı seçeneği ON
olarak ayarlandığında, Veritabanı Altyapısı satır sürümü oluşturma kullanarak verileri işleyen her işleme bir işlem sırası numarası (XSN) atar. İşlemler bir BEGIN TRANSACTION
deyimi yürütüldüğünde başlar. Ancak işlem sırası numarası, BEGIN TRANSACTION
deyiminden sonraki ilk okuma veya yazma işlemiyle başlar. İşlem sıra numarası her atandığında bir kez artırılır.
READ_COMMITTED_SNAPSHOT
veya ALLOW_SNAPSHOT_ISOLATION
veritabanı seçenekleri ON
olarak ayarlandığında, veritabanında gerçekleştirilen tüm veri değişiklikleri için mantıksal kopyalar (sürümler) korunur. Bir satır belirli bir işlem tarafından her değiştirildiğinde Veritabanı Altyapısı örneği, satırın daha önce kaydedilmiş görüntüsünün bir sürümünü sürüm deposunda depolar. Her sürüm, değişikliği yapan işlemin işlem sırası numarasıyla işaretlenir. Değiştirilen satırların sürümleri bir bağlantı listesi kullanılarak zincirlenir. En yeni satır değeri her zaman geçerli veritabanında depolanır ve sürüm deposundaki sürümlenmiş satırlara zincirlenmiştir.
Not
Büyük nesnelerin (LOB) değiştirilmesi için, sürüm deposuna yalnızca değiştirilen parça kopyalanır.
Satır sürümleri, satır sürümüne dayalı yalıtım düzeyleri altında çalışan işlemlerin gereksinimlerini karşılamak için yeterince uzun tutulur. Veritabanı Altyapısı, en erken yararlı işlem sırası numarasını izler ve en eski yararlı sıra numarasından daha düşük olan işlem sırası numaralarıyla damgalanmış tüm satır sürümlerini düzenli aralıklarla siler.
Her iki veritabanı seçeneği de OFF
olarak ayarlandığında, yalnızca tetikleyiciler veya MARS oturumları tarafından değiştirilen veya çevrimiçi dizin işlemleri tarafından okunan satırlar sürümlenir. Bu satır sürümleri artık gerekli olmadığında çıkartılır. Arka planda çalışan bir işlem eski satır sürümlerini giderir.
Not
Kısa süreli işlemler için değiştirilmiş bir satırın bir sürümü, sürüm deposuna yazılmadan önce arabellek havuzunda önbelleğe alınabilir. Sürüme alınan satıra ihtiyaç kısa süreliyse, satır arabellek havuzundan çıkarılır ve G/Ç yükü oluşturmaz.
Verileri okurken davranış
Satır sürüm oluşturma tabanlı yalıtım altında çalışan işlemler, okunan veriler üzerinde paylaşılan (S
) kilit almadıkları için, verileri değiştiren işlemleri engellemez. Ayrıca, alınan kilit sayısının azaltılmasıyla, kaynakları kilitleme yükü de en aza indirilir. Satır sürüm oluşturma ve READ COMMITTED
yalıtımı kullanılarak SNAPSHOT
yalıtımı, sürüme alınan verilerin deyim düzeyinde veya işlem düzeyinde okuma tutarlılığını sağlayacak şekilde tasarlanmıştır.
Satır sürüm oluşturma tabanlı yalıtım düzeyleri altında çalışan işlemler de dahil olmak üzere tüm sorgular derleme ve yürütme sırasında şema kararlılığı (Sch-S
) kilitleri alır. Bu nedenle, eşzamanlı bir işlem tabloda şema değişikliği (Sch-M
) kilidi tuttuğunda sorgular engellenir. Örneğin, veri tanımı dili (DDL) işlemi tablonun şema bilgilerini değiştirmeden önce bir Sch-M
kilidi alır. Satır sürümü esas alan yalıtım düzeyinde çalışan işlemler de dahil olmak üzere, işlemler bir Sch-S
kilidi almaya çalıştıklarında engellenir. Buna karşılık, Sch-S
kilidi tutan bir sorgu, Sch-M
kilidi almaya çalışan eşzamanlı işlemi engeller.
SNAPSHOT
yalıtım düzeyini kullanan bir işlem başlatıldığında, Veritabanı Altyapısı örneği geçerli durumdaki tüm etkin işlemleri kaydeder.
SNAPSHOT
işlemi, sürüm zinciri olan bir satırı okuduğunda, Veritabanı Motoru zinciri takip eder ve işlem dizisi numarasının yer aldığı satırı alır.
Anlık görüntü işleminin satırı okuma sırasındaki sıra numarasına en yakın ancak daha düşük olan.
Anlık görüntü işlemi başlatıldığında etkin işlemler listesinde yer almaz.
bir SNAPSHOT
işlemi tarafından gerçekleştirilen okuma işlemleri, SNAPSHOT
işleminin başlatıldığı sırada kaydedilmiş olan her satırın son sürümünü alır. Bu, işlemin başlangıcında mevcut olan verilerin işlem açısından tutarlı bir anlık görüntüsünü sağlar.
Satır sürümü oluşturma kullanan READ COMMITTED
işlemleri de aynı şekilde çalışır. Fark, READ COMMITTED
işleminin satır sürümlerini seçerken kendi işlem dizisi numarasını kullanmamasıdır. Her bir deyim başlatıldığında, READ COMMITTED
işlemi Veritabanı Motoru'nun ilgili örneği için verilen en son işlem dizisi numarasını okur. Bu, bu deyimin satır sürümlerini seçmek için kullanılan işlem dizisi numarasıdır. Bu, READ COMMITTED
işlemlerin her deyimin başında mevcut olan verilerin anlık görüntüsünü görmesine olanak tanır.
Not
Satır sürümü oluşturma kullanan READ COMMITTED
işlemler, verilerin deyim düzeyinde işlem açısından tutarlı bir görünümünü sağlasa da, bu işlem türü tarafından oluşturulan veya erişilen satır sürümleri, işlem tamamlanana kadar korunur.
Verileri değiştirirken davranış
İyileştirilmiş kilitleme etkinken ve etkinleştirilmeden veri yazma işlemleri farklıdır.
İyileştirilmiş kilitleme olmadan verileri değiştirme
Satır sürümleme kullanan READ COMMITTED
bir işlemde, güncellenecek satırların seçimi, veri değerleri okunurken veri satırında bir güncelleme (U
) kilidinin alındığı bloke edici bir tarama kullanılarak yapılır. Bu, satır sürümü oluşturma kullanmayan bir READ COMMITTED
işlemiyle aynıdır. Veri satırı güncelleştirme ölçütlerini karşılamıyorsa, bu satırda güncelleştirme kilidi serbest bırakılır ve sonraki satır kilitlenir ve taranır.
SNAPSHOT
yalıtımı altında çalışan işlemler, yalnızca kısıtlamaları zorlamak için değişiklik yapmadan önce veriler üzerinde kilitler alarak veri değişikliğine iyimser bir yaklaşım benimser. Aksi takdirde, veriler değiştirilinceye kadar veriler üzerinde kilitler alınmaz. Bir veri satırı güncelleştirme ölçütlerini karşıladığında, SNAPSHOT
işlemi veri satırının SNAPSHOT
işlemi başladıktan sonra işlenen eşzamanlı bir işlem tarafından değiştirilmediğini doğrular. Veri satırı SNAPSHOT
işleminin dışında değiştirilmişse bir güncelleştirme çakışması oluşur ve SNAPSHOT
işlemi sonlandırılır. Güncelleştirme çakışması Veritabanı Altyapısı tarafından işlenir ve güncelleştirme çakışması algılamasını devre dışı bırakmanın hiçbir yolu yoktur.
Not
SNAPSHOT
işlemi aşağıdakilerden birine eriştiğinde, READ COMMITTED
izolasyonu altında çalışan güncelleştirme işlemleri dahili olarak SNAPSHOT
izolasyonu altında yürütülür.
Yabancı anahtar kısıtlaması olan bir tablo.
Başka bir tablonun yabancı anahtar kısıtlamasında referans verilen bir tablo.
Birden fazla tabloya başvuran dizinli görünüm.
Ancak, bu koşullar altında bile güncelleştirme işlemi verilerin başka bir işlem tarafından değiştirilmediğini doğrulamaya devam eder. Veriler başka bir işlem tarafından değiştirildiyse, SNAPSHOT
işlemi bir güncelleştirme çakışması ile karşılaşır ve sonlandırılır. Güncelleştirme çakışmaları uygulama tarafından işlenmeli ve yeniden denenmelidir.
İyileştirilmiş kilitleme ile verileri değiştirme
İyileştirilmiş kilitleme etkinken ve READ_COMMITTED_SNAPSHOT
(RCSI) veritabanı seçeneği etkinken ve varsayılan READ COMMITTED
yalıtım düzeyini kullanarak okuyucular hiçbir kilit almaz ve yazarlar işlemin sonunda süresi dolan kilitler yerine kısa süreli düşük düzeyli kilitler alır.
RCSI'nin etkinleştirilmesi, iyileştirilmiş kilitleme ile çoğu verimlilik için önerilir.
REPEATABLE READ
veya SERIALIZABLE
gibi daha katı yalıtım düzeylerini kullanırken, Veritabanı Altyapısı hem okuyucular hem de yazarlar için işlemin sonuna kadar satır ve sayfa kilitleri tutar ve bu da belleğin engellenmesine ve kilitlenmesine neden olur.
RCSI etkinleştirildiğinde ve varsayılan READ COMMITTED
yalıtım seviyesini kullanırken, yazarlar U
kilitleri almadan, satırın en son işlenmiş sürümüne göre şarta göre satırları niteler. Sorgu, yalnızca satır uygunsa ve o satırda veya sayfada zaten başka bir etkin yazma işlemi varsa bekler. En son taahhüt edilen sürüme göre nitelemek ve sadece nitelikli satırları kilitlemek, engellemeyi azaltır ve eşzamanlılığı artırır.
RCSI ile ve varsayılan READ COMMITTED
yalıtım düzeyinde güncelleştirme çakışmaları algılanırsa, müşteri iş yüklerini etkilemeden otomatik olarak işlenir ve yeniden denenir.
İyileştirilmiş kilitleme etkinken ve SNAPSHOT
yalıtım düzeyini kullanırken güncelleştirme çakışmalarının davranışı, iyileştirilmiş kilitleme olmadan olduğu gibi aynıdır. Güncelleştirme çakışmaları uygulama tarafından işlenmeli ve yeniden denenmelidir.
Not
İyileştirilmiş kilitlemenin niteleme (LAQ) özelliğinden sonra kilitle ilgili davranış değişiklikleri hakkında daha fazla bilgi için bkz. İyileştirilmiş kilitleme ile davranış değişikliklerini sorgulama ve RCSI.
Özetteki davranış
Aşağıdaki tabloda, satır sürümleme kullanılarak SNAPSHOT
yalıtımı ile READ COMMITTED
yalıtımı arasındaki farklar özetlenmektedir.
Mülk |
READ COMMITTED satır sürümü kullanarak yalıtım seviyesi |
SNAPSHOT yalıtım düzeyi |
---|---|---|
Gerekli desteği etkinleştirmek için ON olarak ayarlanması gereken veritabanı seçeneği. |
READ_COMMITTED_SNAPSHOT |
ALLOW_SNAPSHOT_ISOLATION |
Oturumun belirli bir satır sürümü türünü talep etme şekli. | Varsayılan READ COMMITTED yalıtım düzeyini kullanın veya SET TRANSACTION ISOLATION LEVEL yalıtım düzeyini belirtmek için READ COMMITTED deyimini çalıştırın. İşlem başladıktan sonra bu yapılabilir. |
İşlem başlamadan önce SET TRANSACTION ISOLATION LEVEL yalıtım düzeyini belirtmek için SNAPSHOT yürütülmesini gerektirir. |
İfadeler tarafından okunan verilerin sürümü. | Her deyimin başlangıcından önce işlenen tüm veriler. | Her işlem başlamadan önce işlenen tüm veriler. |
Güncelleştirmelerin nasıl işleneceğini. |
İyileştirilmiş kilitleme olmadan: Güncelleştirilecek satırları seçmek için satır sürümlerinden gerçek verilere geri döner ve seçilen veri satırlarında güncelleştirme kilitlerini kullanır. Değiştirilecek gerçek veri satırlarında özel kilitler alır. Güncelleştirme çakışması algılaması yok. İyileştirilmiş kilitleme ile: Satırlar, hiçbir kilit alınmadan son onaylanmış sürüme göre seçilir. Satırların güncelleştirme için uygun olması durumunda, tahsisli satır veya sayfa kilitleri alınır. Güncelleştirme çakışmaları algılanırsa, bunlar otomatik olarak işlenir ve yeniden denener. |
Güncelleştirilecek satırları seçmek için satır sürümlerini kullanır. Değiştirilecek gerçek veri satırında özel kilit almaya çalışır ve veriler başka bir işlem tarafından değiştirilmişse bir güncelleme çakışması oluşur ve anlık işlem sonlandırılır. |
Güncelleştirme çakışması algılama |
İyileştirilmiş kilitleme olmadan: Yok. İyileştirilmiş kilitleme ile: Güncelleştirme çakışmaları algılanırsa, bunlar otomatik olarak işlenir ve yeniden denener. |
Tümleşik destek. Devre dışı bırakılamaz. |
Satır sürüm oluşturma kaynak kullanımı
Satır sürüm oluşturma çerçevesi aşağıdaki Veritabanı Altyapısı özelliklerini destekler:
- Tetikleyiciler
- Birden Çok Etkin Sonuç Kümesi (MARS)
- Çevrimiçi dizin oluşturma
Satır sürüm oluşturma çerçevesi aşağıdaki satır sürüm oluşturma tabanlı işlem yalıtım düzeylerini de destekler:
-
READ_COMMITTED_SNAPSHOT
veritabanı seçeneğiON
olarak ayarlandığında,READ_COMMITTED
işlemler satır sürümleme kullanılarak ifade düzeyinde okuma tutarlılığı sunar. -
ALLOW_SNAPSHOT_ISOLATION
veritabanı seçeneğiON
olarak ayarlandığında,SNAPSHOT
işlemler satır sürümü oluşturma kullanılarak işlem düzeyinde okuma tutarlılığı sağlar.
Satır sürümleme tabanlı yalıtım düzeyleri, okuma işlemlerinde paylaşılan kilitlerin kullanımını ortadan kaldırarak her işlem tarafından alınan kilit sayısını azaltır. Bu, kilitleri yönetmek için kullanılan kaynakları azaltarak sistem performansını artırır. Diğer işlemler tarafından alınan kilitler nedeniyle bir işlemin engellenme miktarı azaltılarak performans da artar.
Satır sürümü oluşturma tabanlı yalıtım düzeyleri, veri değişiklikleri için gereken kaynakları artırır. Bu seçeneklerin etkinleştirilmesi, veritabanının tüm veri değişikliklerinin sürümüne neden olur. Satır sürüm oluşturma tabanlı yalıtım kullanan etkin işlemler olmasa bile değişiklik yapılmadan önce verilerin bir kopyası sürüm deposunda depolanır. Değişiklik sonrasındaki veriler, sürüm deposundaki sürümlenmiş verilere yönelik bir işaretçi içerir. Büyük nesneler için, değiştirilen nesnenin yalnızca bir bölümü sürüm deposunda depolanır.
Tempdb'de kullanılan alan
Veritabanı Altyapısı'nın her örneği için, sürüm deposunun satır sürümlerini tutmak için yeterli alana sahip olması gerekir. Veritabanı yöneticisi, tempdb
ve diğer veritabanlarının (ADR etkinse) sürüm depoyu desteklemek için bol alana sahip olduğundan emin olmalıdır. İki tür sürüm deposu vardır:
- Çevrimiçi dizin derleme sürümü deposu, çevrimiçi dizin derlemeleri için kullanılır.
- Ortak sürüm deposu, diğer tüm veri değiştirme işlemleri için kullanılır.
Satır sürümleri, etkin bir işlemin bunlara erişmesi gerektiği sürece depolanmalıdır. Arka plan iş parçacığı, artık gerekli olmayan satır sürümlerini düzenli aralıklarla kaldırır ve sürüm deposunda alan açar. Uzun süre çalışan bir işlem, aşağıdaki koşullardan herhangi birini karşılıyorsa sürüm deposundaki alanın serbest bırakılmasını engeller:
- Satır sürümleme tabanlı yalıtım kullanır.
- Tetikleyicileri, MARS'ı veya çevrimiçi dizin derleme işlemlerini kullanır.
- Satır sürümleri oluşturur.
Not
Bir işlem içinde bir tetikleyici çağrıldığında, tetikleyici tarafından oluşturulan satır sürümleri, tetikleyici tamamlandıktan sonra satır sürümleri artık gerekli olmasa bile işlemin sonuna kadar korunur. Bu, satır sürümlemeyi kullanan READ COMMITTED
işlemleri için de geçerlidir. Bu işlem türüyle, veritabanının işlem açısından tutarlı bir görünümü yalnızca işlemdeki her deyim için gereklidir. İşlemdeki bir ifade için oluşturulan satır sürümlerine, ifade tamamlandıktan sonra artık ihtiyaç duyulmaz. İşlemdeki her ifade tarafından oluşturulan satır sürümleri, işlem tamamlanana kadar muhafaza edilir.
Sürüm deposu tempdb
içindeyse ve tempdb
alanı tükeniyorsa, Veritabanı Altyapısı sürüm depolarını küçültmeye zorlar. Küçültme işlemi sırasında, henüz satır sürümleri oluşturulmamış en uzun süre çalışan işlemler kurban olarak işaretlenir. Her bir kurban işlemi için hata günlüğünde 3967 iletisi oluşturulur. Eğer bir işlem bir kurban olarak işaretlenirse, artık sürüm deposundaki satır sürümlerini okuyamaz. Satır sürümlerini okumaya çalıştığında, 3966 numaralı ileti oluşturulur ve transaksiyon geri alınır. Küçültme işlemi başarılı olursa, tempdb
içinde alan kullanılabilir hale gelir. Aksi takdirde, tempdb
alanı biter ve aşağıdakiler gerçekleşir:
Yazma işlemleri yürütülmeye devam ediyor ancak sürüm oluşturmuyor. Hata günlüğünde bir bilgi iletisi (3959) görüntülenir, ancak veri yazan işlem etkilenmez.
tempdb
tam geri alma nedeniyle oluşturulmayan satır sürümlerine erişmeye çalışan işlemler, 3958 hatasıyla sonlandırılır.
Veri satırlarında kullanılan alan
Her veritabanı satırı, satır sürümü oluşturma bilgileri için satırın sonunda en fazla 14 bayt kullanabilir. Satır sürüm oluşturma bilgileri, sürümü işleyen işlemin işlem sırası numarasını ve sürümlenen satırın işaretçisini içerir. Bu 14 bayt, bu koşullardan herhangi biri altında satır ilk değiştirildiğinde veya yeni bir satır eklendiğinde eklenir:
-
READ_COMMITTED_SNAPSHOT
veyaALLOW_SNAPSHOT_ISOLATION
seçenekleriON
olarak ayarlanır. - Tablonun bir tetikleyicisi vardır.
- Birden çok Etkin Sonuç Kümesi (MARS) kullanılıyor.
- Çevrimiçi dizin oluşturma işlemleri şu anda tablo üzerinde çalışıyor.
- Hızlandırılmış veritabanı kurtarma (ADR) etkinleştirildi.
Bu 14 bayt, bu koşulların tümü altında ilk kez değiştirildiğinde veritabanı satırından kaldırılır:
-
READ_COMMITTED_SNAPSHOT
veALLOW_SNAPSHOT_ISOLATION
seçenekleriOFF
olarak ayarlanır. - Tetikleyici artık tabloda yok.
- MARS kullanılmıyor.
- Çevrimiçi dizin derleme işlemleri şu anda çalışmıyor.
- Hızlandırılmış veritabanı kurtarma (ADR) devre dışı bırakıldı.
Satır sürümü oluşturma özelliklerinden herhangi birini kullanırsanız, veritabanı satırı başına 14 baytı barındırmak için veritabanı için ek disk alanı ayırmanız gerekebilir. Satır sürümleme bilgisinin eklenmesi, geçerli sayfada yeterli alan yoksa dizin sayfasının bölünmesine veya yeni bir veri sayfasının ayrılmasına neden olabilir. Örneğin, ortalama satır uzunluğu 100 baytsa, ek 14 bayt var olan bir tablonun yüzde 14'e kadar büyümesine neden olur.
doldurma faktörü azaltmak, dizin sayfalarının parçalanmasını önlemeye veya azaltmaya yardımcı olabilir. Tablo veya görünümün verilerine ve dizinlerine ilişkin geçerli sayfa yoğunluğu bilgilerini görüntülemek için sys.dm_db_index_physical_statskullanabilirsiniz.
Kalıcı sürüm deposu (PVS) tarafından kullanılan alan
ADR etkinleştirildiğinde, satır sürümleri, değişiklik öncesinde satırın boyutuna bağlı olarak aşağıdaki yollardan biriyle kalıcı sürüm deposunda (PVS) depolanabilir:
- Boyut küçükse, eski satır sürümünün tamamı değiştirilen satırın bir parçası olarak depolanır.
- Boyut ara değerse, eski satır sürümü ile değiştirilen satır arasındaki fark, değiştirilen satırın bir parçası olarak depolanır. Fark, veritabanı altyapısının gerekirse tüm eski satır sürümünü yeniden oluşturmasına olanak sağlayacak şekilde oluşturulur.
- Boyut büyükse, eski satır sürümünün tamamı ayrı bir iç tabloda depolanır.
İlk iki yöntem satır içi sürüm depolama olarak adlandırılır. Son yöntem, satır dışı sürüm depolama olarak adlandırılır. Satır içi sürümlere artık ihtiyaç duyulmadığında, sayfalarda yer açmak için bunlar kaldırılır. Benzer şekilde, iç tablodaki artık gerekli olmayan satır dışı sürümleri içeren sayfalar sürüm temizleyicisi tarafından kaldırılır.
Satır sürümlerini satırın bir parçası olarak depolamak, satır sürümlerini okuması gereken işlemler için veri alımını iyileştirir. Sürüm satır içinde depolanıyorsa, satır dışı PVS sayfasının ayrı bir okunması gerekmez.
sys.dm_db_index_physical_stats DMV, dizinin bir bölümü için satır içinde ve satır dışında depolanan sürümlerin sayısını ve türünü sağlar. Satır içinde depolanan sürüm verilerinin toplam boyutu total_inrow_version_payload_size_in_bytes
sütununda bildirilir.
Satır dışı sürüm depolama alanının boyutu, persistent_version_store_size_kb
DMV'deki sütununda bildirilir.
Büyük nesnelerde kullanılan alan
Veritabanı Altyapısı, 2 gigabayt (GB) uzunluğa kadar büyük dizeleri tutabilen çeşitli veri türlerini destekler: nvarchar(max)
, varchar(max)
, varbinary(max)
, ntext
, text
ve image
. Bu veri türleri kullanılarak depolanan büyük veriler, veri satırına bağlı bir dizi veri parçasında depolanır. Satır sürüm oluşturma bilgileri, bu büyük dizeleri depolamak için kullanılan her parçada depolanır. Veri parçaları, bir tablodaki büyük nesnelere ayrılmış bir sayfa kümesinde depolanır.
Veritabanına yeni büyük değerler eklendikçe, bunlar parça başına en fazla 8040 bayt veri kullanılarak ayrılır. Veritabanı Altyapısı'nın önceki sürümleri parça başına en fazla 8080 bayt ntext
, text
veya image
veri depoladı.
Var olan ntext
, text
ve image
büyük nesne (LOB) verileri, bir veritabanı SQL Server'ın önceki bir sürümünden SQL Server'a yükseltildiğinde satır sürümü oluşturma bilgilerine yer açmak için güncelleştirilmez. Ancak, LOB verileri ilk kez değiştirildiğinde, sürüm oluşturma bilgilerinin depolanmasını etkinleştirmek için dinamik olarak yükseltilir. Satır sürümleri oluşturulmasa bile bu durum oluşur. LOB verileri yükseltildikten sonra, parça başına depolanan bayt sayısı üst sınırı 8080 bayttan 8040 bayta indirilir. Yükseltme işlemi, LOB değerini silmeye ve aynı değeri yeniden başlatmaya eşdeğerdir. Yalnızca 1 bayt değiştirilse bile LOB verileri yükseltilir. Bu, her ntext
, text
veya image
sütunu için tek seferlik bir işlemdir, ancak her işlem LOB verilerinin boyutuna bağlı olarak büyük miktarda sayfa ayırma ve G/Ç etkinliği oluşturabilir. Ayrıca, değişiklik tamamen günlüğe kaydedilirse büyük miktarda günlük etkinliği oluşturabilir. Veritabanı kurtarma modeli FULL olarak ayarlı değilse WRITETEXT
ve UPDATETEXT
işlemleri en az seviyede günlüğe kaydedilir.
Bu gereksinimi karşılamak için yeterli disk alanı ayrılmalıdır.
Satır sürümünü ve sürüm deposunu izleme
Veritabanı Altyapısı, performans ve sorunlara yönelik satır sürüm oluşturma, sürüm deposu ve anlık görüntü yalıtım işlemlerini izlemek için Dinamik Yönetim Görünümleri (DMV) ve performans sayaçları biçiminde araçlar sağlar.
DMV'ler
Aşağıdaki DMV'ler, tempdb
'ın ve sürüm deposunun geçerli sistem durumu hakkında, ayrıca satır sürümü kullanan işlemler hakkında bilgi sağlar.
sys.dm_db_file_space_usage
. Veritabanındaki her dosya için alan kullanım bilgilerini döndürür. Daha fazla bilgi için bkz. sys.dm_db_file_space_usage (Transact-SQL).sys.dm_db_session_space_usage
. Veritabanı için oturuma göre sayfa ayırma ve serbest bırakma etkinliğini döndürür. Daha fazla bilgi için bkz. sys.dm_db_session_space_usage (Transact-SQL).sys.dm_db_task_space_usage
. Veritabanı için göreve göre sayfa ayırma ve serbest bırakma etkinliğini döndürür. Daha fazla bilgi için bkz. sys.dm_db_task_space_usage (Transact-SQL).sys.dm_tran_top_version_generators
. Sürüm deposunda en çok sürümü oluşturan nesneler için bir sanal tablo döndürür. İlk 256 toplam kayıt uzunluğunu database_id ve rowset_id göre gruplandırıyor. Sürüm deposunun en büyük tüketicilerini bulmak için bu işlevi kullanın. Yalnızcatempdb
sürüm deposu için geçerlidir. Daha fazla bilgi için bkz. sys.dm_tran_top_version_generators (Transact-SQL).sys.dm_tran_version_store
. Ortak sürüm deposundaki tüm sürüm kayıtlarını görüntüleyen bir sanal tablo döndürür. Yalnızcatempdb
sürüm deposu için geçerlidir. Daha fazla bilgi için bkz. sys.dm_tran_version_store (Transact-SQL).sys.dm_tran_version_store_space_usage
. Her veritabanı için sürüm deposu kayıtları tarafından kullanılan toplamtempdb
alanını gösteren bir sanal tablo döndürür. Yalnızcatempdb
sürüm deposu için geçerlidir. Daha fazla bilgi için bkz. sys.dm_tran_version_store_space_usage (Transact-SQL).Not
sys.dm_tran_top_version_generators
vesys.dm_tran_version_store
sorgulamak pahalı olabilir çünkü her ikisi de büyük olabilecek sürüm deposunun tamamını tarar.sys.dm_tran_version_store_space_usage
verimlidir ve tek tek sürüm deposu kayıtlarında gezinmediğinden ve bunun yerine veritabanı başınatempdb
tüketilen toplu sürüm deposu alanını döndürdüğünden çalıştırılması pahalı değildir.sys.dm_tran_active_snapshot_database_transactions
. SQL Server örneğindeki satır sürümü oluşturmayı kullanan tüm veritabanlarındaki tüm etkin işlemler için bir sanal tablo döndürür. Sistem işlemleri bu DMV'de görünmez. Daha fazla bilgi için bkz. sys.dm_tran_active_snapshot_database_transactions (Transact-SQL).sys.dm_tran_transactions_snapshot
. Her işlem tarafından alınan anlık görüntüleri görüntüleyen bir sanal tablo döndürür. Anlık görüntü, satır sürümleme kullanan etkin işlemlerin sıra numarasını içerir. Daha fazla bilgi için bkz. sys.dm_tran_transactions_snapshot (Transact-SQL).sys.dm_tran_current_transaction
. Geçerli oturumdaki işlemin sürüm oluşturmayla ilgili durum bilgilerini gösteren tek bir satır döndürülür. Daha fazla bilgi için bkz. sys.dm_tran_current_transaction (Transact-SQL).sys.dm_tran_current_snapshot
. Geçerli anlık görüntü yalıtım işlemi başlatıldığında tüm etkin işlemleri görüntüleyen bir sanal tablo döndürür. Geçerli işlem anlık görüntü yalıtımı kullanıyorsa, bu işlev satır döndürmez. DMVsys.dm_tran_current_snapshot
, yalnızca geçerli anlık görüntüdeki etkin işlemleri döndürmesi dışındasys.dm_tran_transactions_snapshot
'e benzer. Daha fazla bilgi için bkz. sys.dm_tran_current_snapshot (Transact-SQL).sys.dm_tran_persistent_version_store_stats
. Hızlandırılmış veritabanı kurtarma etkinleştirildiğinde kullanılan her veritabanındaki kalıcı sürüm deposunun istatistiklerini döndürür. Daha fazla bilgi için bkz. sys.dm_tran_persistent_version_store_stats (Transact-SQL).
Performans sayaçları
Aşağıdaki performans sayaçları, tempdb
içindeki sürüm deposunu ve satır sürümü kullanarak işlem yapan işlemleri izler. Performans sayaçları SQLServer:Transactions
performans nesnesinde yer alır.
tempdb'de (KB) boş alan.
tempdb
veritabanındaki boş alan miktarını kilobayt (KB) cinsinden izler. Anlık görüntü yalıtımını destekleyen sürüm deposunu işlemek içintempdb
'da yeterli boş alan bulunmalıdır.Aşağıdaki formül, sürüm deposunun boyutuna ilişkin kabaca bir tahmin sağlar. Uzun süre çalışan işlemler için, sürüm deposunun maksimum boyutunu tahmin etmek için oluşturma ve temizleme hızını izlemek yararlı olabilir.
[ortak sürüm deposunun boyutu] = 2 * [dakikada oluşturulan sürüm deposu verileri] * [işlemin en uzun çalışma süresi (dakika)]
İşlemlerin en uzun çalışma süresi çevrimiçi dizin derlemelerini içermemelidir. Bu işlemler çok büyük tablolarda uzun sürebileceğinden, çevrimiçi dizin derlemeleri ayrı bir sürüm deposu kullanır. Çevrimiçi dizin derleme sürümü deposunun yaklaşık boyutu, çevrimiçi dizin derlemesi etkinken tüm dizinler de dahil olmak üzere tabloda değiştirilen veri miktarına eşittir.
Sürüm Deposu Boyutu (KB).
tempdb
'deki tüm sürüm depolarının KB cinsinden boyutunu izler. Bu bilgiler, sürüm deposu içintempdb
veritabanında gereken alan miktarını belirlemeye yardımcı olur. Bu sayacın belirli bir süre boyunca izlenmesi,tempdb
için gereken ek alanın yararlı bir tahminini sağlar.Sürüm Oluşturma hızı (KB/sn).
tempdb
'deki tüm sürüm depolarında kb/saniye cinsinden sürüm oluşturma hızını izler.Sürüm Temizleme hızı (KB/sn).
tempdb
'deki tüm sürüm depolarında sürüm temizleme hızını kb/saniye cinsinden izler.Not
tempdb
alan gereksinimlerini tahmin etmek için Sürüm Oluşturma hızı (KB/sn) ve Sürüm Temizleme hızı (KB/sn) bilgileri kullanılabilir.Sürüm Deposu birim sayısı. Sürüm deposu birimlerinin sayısını izler.
Sürüm Deposu birimi oluşturma. Örnek başlatıldıktan sonra satır sürümlerini depolamak için oluşturulan toplam sürüm deposu birimi sayısını izler.
Sürüm Deposu biriminin kesilmesi. Örnek başlatıldığından beri kesilen sürüm deposu birimlerinin toplam sayısını izler. SQL Server, etkin işlemleri çalıştırmak için sürüm deposu biriminde depolanan sürüm satırlarından hiçbirinin gerekli olmadığını belirlediğinde bir sürüm deposu birimi kesilir.
Çakışma oranını güncelleştirin. Güncelleştirme çakışmaları olan güncelleştirme anlık görüntüsü işlemlerinin toplam güncelleştirme anlık görüntüsü işlemi sayısına oranını izler.
En Uzun İşlem Çalışma Süresi. Satır sürümleme kullanarak herhangi bir işlemin saniye cinsinden en uzun çalışma süresini izler. Bu, beklenmeyen bir süre boyunca herhangi bir işlemin çalışıp çalışmadığını belirlemek için kullanılabilir.
İşlemler. Toplam etkin işlem sayısını izler. Buna sistem işlemleri dahil değildir.
Anlık Görüntü İşlemleri. Etkin anlık görüntü işlemlerinin toplam sayısını izler.
Anlık Görüntü İşlemlerini Güncelleştir. Güncelleştirme işlemlerini gerçekleştiren etkin anlık görüntü işlemlerinin toplam sayısını izler.
Anlık Görüntü Olmayan Sürüm İşlemleri. Sürüm kayıtları oluşturan anlık görüntü olmayan etkin işlemlerin toplam sayısını izler.
Not
Güncelleştirme Anlık Görüntüsü İşlemleri ve Ekran Görüntüsü Olmayan Sürüm İşlemlerinin toplamı, sürüm oluşturma işlemine katılan toplam işlem sayısını temsil eder. Anlık Görüntü İşlemleri ile Anlık Görüntü İşlemlerini Güncelleştir arasındaki fark, salt okunur anlık görüntü işlemlerinin sayısını temsil eder.
Satır sürümleme tabanlı yalıtım seviyesi örneği
Aşağıdaki örneklerde, SNAPSHOT
yalıtım işlemleri ile satır sürümü oluşturma kullanan READ COMMITTED
işlemleri arasındaki davranış farklılıkları gösterilmektedir.
A. SNAPSHOT izolasyonuyla çalışmak
Bu örnekte, SNAPSHOT
yalıtımı altında çalışan bir işlem, daha sonra başka bir işlem tarafından değiştirilen verileri okur.
SNAPSHOT
işlemi, diğer işlem tarafından yürütülen güncelleştirme işlemini engellemez ve veri değişikliğini yoksayarak sürümlenen satırdaki verileri okumaya devam eder. Ancak, SNAPSHOT
işlemi diğer işlem tarafından önceden değiştirilmiş olan verileri değiştirmeye çalıştığında, SNAPSHOT
işlemi bir hata oluşturur ve sonlandırılır.
Oturum 1'de:
USE AdventureWorks2022;
GO
-- Enable snapshot isolation on the database.
ALTER DATABASE AdventureWorks2022 SET ALLOW_SNAPSHOT_ISOLATION ON;
GO
-- Start a snapshot transaction
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
GO
BEGIN TRANSACTION;
-- This SELECT statement will return
-- 48 vacation hours for the employee.
SELECT BusinessEntityID, VacationHours
FROM HumanResources.Employee
WHERE BusinessEntityID = 4;
2. oturumda:
USE AdventureWorks2022;
GO
-- Start a transaction.
BEGIN TRANSACTION;
-- Subtract a vacation day from employee 4.
-- Update is not blocked by session 1 since
-- under snapshot isolation shared locks are
-- not requested.
UPDATE HumanResources.Employee
SET VacationHours = VacationHours - 8
WHERE BusinessEntityID = 4;
-- Verify that the employee now has 40 vacation hours.
SELECT VacationHours
FROM HumanResources.Employee
WHERE BusinessEntityID = 4;
Oturum 1'de:
-- Reissue the SELECT statement - this shows
-- the employee having 48 vacation hours. The
-- snapshot transaction is still reading data from
-- the older, versioned row.
SELECT BusinessEntityID, VacationHours
FROM HumanResources.Employee
WHERE BusinessEntityID = 4;
2. oturumda:
-- Commit the transaction; this commits the data
-- modification.
COMMIT TRANSACTION;
GO
Oturum 1'de:
-- Reissue the SELECT statement - this still
-- shows the employee having 48 vacation hours
-- even after the other transaction has committed
-- the data modification.
SELECT BusinessEntityID, VacationHours
FROM HumanResources.Employee
WHERE BusinessEntityID = 4;
-- Because the data has been modified outside of the
-- snapshot transaction, any further data changes to
-- that data by the snapshot transaction will cause
-- the snapshot transaction to fail. This statement
-- will generate a 3960 error and the transaction will
-- terminate.
UPDATE HumanResources.Employee
SET SickLeaveHours = SickLeaveHours - 8
WHERE BusinessEntityID = 4;
-- Undo the changes to the database from session 1.
-- This will not undo the change from session 2.
ROLLBACK TRANSACTION;
GO
B. Satır sürümlemesini kullanarak READ COMMITTED izolasyonu ile çalışma
Bu örnekte, satır sürümü oluşturma kullanan bir READ COMMITTED
işlemi başka bir işlemle eşzamanlı olarak çalıştırılır.
READ COMMITTED
işlemi, SNAPSHOT
işlemden farklı davranır. bir SNAPSHOT
işlemi gibi, READ COMMITTED
işlemi de diğer işlem verileri değiştirdikten sonra bile sürümlenmiş satırları okur. Ancak, SNAPSHOT
işlemden farklı olarak, READ COMMITTED
işlemi:
- Diğer işlem veri değişikliklerini işledikten sonra değiştirilen verileri okur.
- Diğer işlem tarafından değiştirilen ve
SNAPSHOT
işleminin güncelleyemediği verileri güncelleyebilir.
Oturum 1'de:
USE AdventureWorks2022;
GO
-- Enable READ_COMMITTED_SNAPSHOT on the database.
-- For this statement to succeed, this session
-- must be the only connection to the AdventureWorks2022
-- database.
ALTER DATABASE AdventureWorks2022 SET READ_COMMITTED_SNAPSHOT ON;
GO
-- Start a read-committed transaction
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
GO
BEGIN TRANSACTION;
-- This SELECT statement will return
-- 48 vacation hours for the employee.
SELECT BusinessEntityID, VacationHours
FROM HumanResources.Employee
WHERE BusinessEntityID = 4;
2. oturumda:
USE AdventureWorks2022;
GO
-- Start a transaction.
BEGIN TRANSACTION;
-- Subtract a vacation day from employee 4.
-- Update is not blocked by session 1 since
-- under read-committed using row versioning shared locks are
-- not requested.
UPDATE HumanResources.Employee
SET VacationHours = VacationHours - 8
WHERE BusinessEntityID = 4;
-- Verify that the employee now has 40 vacation hours.
SELECT VacationHours
FROM HumanResources.Employee
WHERE BusinessEntityID = 4;
Oturum 1'de:
-- Reissue the SELECT statement - this still shows
-- the employee having 48 vacation hours. The
-- read-committed transaction is still reading data
-- from the versioned row and the other transaction
-- has not committed the data changes yet.
SELECT BusinessEntityID, VacationHours
FROM HumanResources.Employee
WHERE BusinessEntityID = 4;
2. oturumda:
-- Commit the transaction.
COMMIT TRANSACTION;
GO
Oturum 1'de:
-- Reissue the SELECT statement which now shows the
-- employee having 40 vacation hours. Being
-- read-committed, this transaction is reading the
-- committed data. This is different from snapshot
-- isolation which reads from the versioned row.
SELECT BusinessEntityID, VacationHours
FROM HumanResources.Employee
WHERE BusinessEntityID = 4;
-- This statement, which caused the snapshot transaction
-- to fail, will succeed with read-committed using row versioning.
UPDATE HumanResources.Employee
SET SickLeaveHours = SickLeaveHours - 8
WHERE BusinessEntityID = 4;
-- Undo the changes to the database from session 1.
-- This will not undo the change from session 2.
ROLLBACK TRANSACTION;
GO
Satır sürüm oluşturma tabanlı yalıtım düzeylerini etkinleştirme
Veritabanı yöneticileri, READ_COMMITTED_SNAPSHOT
deyimindeki ALLOW_SNAPSHOT_ISOLATION
ve ALTER DATABASE
veritabanı seçeneklerini kullanarak satır sürümü oluşturma için veritabanı düzeyi ayarlarını denetler.
READ_COMMITTED_SNAPSHOT
veritabanı seçeneği ON
olarak ayarlandığında, seçeneği desteklemek için kullanılan mekanizmalar hemen etkinleştirilir.
READ_COMMITTED_SNAPSHOT
seçeneğini ayarlarken, veritabanında yalnızca ALTER DATABASE
komutunu yürüten bağlantıya izin verilir.
ALTER DATABASE
tamamlanana kadar veritabanında başka açık bağlantı olmamalıdır. Veritabanının tek kullanıcılı modda olması gerekmez.
Aşağıdaki Transact-SQL deyimi READ_COMMITTED_SNAPSHOT
etkinleştirir:
ALTER DATABASE AdventureWorks2022 SET READ_COMMITTED_SNAPSHOT ON;
ALLOW_SNAPSHOT_ISOLATION
veritabanı seçeneği ON
olarak ayarlandığında Veritabanı Altyapısı örneği, veritabanında değiştirilmiş veriler içeren tüm etkin işlemler tamamlanana kadar değiştirilen veriler için satır sürümleri oluşturmaya başlamaz. Etkin değişiklik işlemleri varsa, Veritabanı Altyapısı seçeneğin durumunu PENDING_ON
olarak ayarlar. Tüm değişiklik işlemleri tamamlandıktan sonra seçeneğin durumu ON
olarak değiştirilir. Kullanıcılar, seçenek SNAPSHOT
olmadan veritabanında bir ON
işlemi başlatamaz. Benzer şekilde, veritabanı yöneticisi PENDING_OFF
seçeneğini ALLOW_SNAPSHOT_ISOLATION
olarak ayarladığında veritabanı OFF
durumundan geçer.
Aşağıdaki Transact-SQL deyimi ALLOW_SNAPSHOT_ISOLATION
etkinleştirir:
ALTER DATABASE AdventureWorks2022 SET ALLOW_SNAPSHOT_ISOLATION ON;
Aşağıdaki tabloda ALLOW_SNAPSHOT_ISOLATION
seçeneğinin durumları listelenmiştir ve açıklanmaktadır.
ALTER DATABASE
'un ALLOW_SNAPSHOT_ISOLATION
seçeneğiyle kullanılması, şu anda veritabanı verilerine erişen kullanıcıları engellemez.
Geçerli veritabanı için SNAPSHOT yalıtımının durumu |
Açıklama |
---|---|
OFF |
SNAPSHOT yalıtım işlemleri desteği etkinleştirilmedi.
SNAPSHOT yalıtım işlemine izin verilmez. |
PENDING_ON |
SNAPSHOT yalıtım işlemleri için destek, OFF 'den ON 'ye geçiş durumundadır. Açık işlemler tamamlanmalıdır.SNAPSHOT yalıtım işlemine izin verilmez. |
ON |
SNAPSHOT yalıtım işlemleri desteği etkinleştirilir.SNAPSHOT işlemlere izin verilir. |
PENDING_OFF |
SNAPSHOT yalıtım işlemleri için destek, ON 'den OFF 'ye geçiş durumundadır.Bu süreden sonra başlatılan SNAPSHOT işlemler bu veritabanına erişemez. Mevcut SNAPSHOT işlemleri bu veritabanına erişmeye devam edebilir. Mevcut yazma işlemleri bu veritabanında sürüm oluşturma özelliğini kullanmaya devam eder. Veritabanı PENDING_OFF yalıtım durumu OFF olduğunda başlatılan tüm SNAPSHOT işlemleri bitmeden, durum SNAPSHOT , ON olmaz. |
Her iki satır sürüm oluşturma veritabanı seçeneğinin durumunu belirlemek için sys.databases
katalog görünümünü kullanın.
master
ve msdb
'de depolanan kullanıcı tablolarına ve bazı sistem tablolarına yapılan tüm güncelleştirmeler satır sürümleri oluşturur.
ALLOW_SNAPSHOT_ISOLATION
seçeneği otomatik olarak ON
ve master
veritabanlarında msdb
olarak ayarlanır ve devre dışı bırakılamaz.
Kullanıcılar READ_COMMITTED_SNAPSHOT
seçeneğini ON
, master
veya tempdb
msdb
olarak ayarlayamaz.
Satır sürüm oluşturma tabanlı yalıtım düzeylerini kullanma
Satır sürüm oluşturma çerçevesi her zaman etkindir ve birden çok özellik tarafından kullanılır. Satır sürüm oluşturma tabanlı yalıtım düzeyleri sağlamanın yanı sıra, tetikleyicilerde ve birden çok etkin sonuç kümesi (MARS) oturumunda yapılan değişiklikleri desteklemek ve çevrimiçi dizin işlemleri için veri okumalarını desteklemek için kullanılır.
Satır sürüm oluşturma tabanlı yalıtım düzeyleri veritabanı düzeyinde etkinleştirilir. Etkin veritabanlarından nesnelere erişen tüm uygulamalar aşağıdaki yalıtım düzeylerini kullanarak sorgular çalıştırabilir:
READ COMMITTED
veritabanı seçeneği aşağıdaki kod örneğinde gösterildiği gibiREAD_COMMITTED_SNAPSHOT
olarak ayarlandığında satır sürümlemesi yapanON
:ALTER DATABASE AdventureWorks2022 SET READ_COMMITTED_SNAPSHOT ON;
veritabanı
READ_COMMITTED_SNAPSHOT
için etkinleştirildiğinde,READ COMMITTED
yalıtım düzeyi altında çalışan tüm sorgular satır sürümü oluşturma kullanır; bu da okuma işlemlerinin güncelleştirme işlemlerini engellemediği anlamına gelir.Aşağıdaki kod örneğinde gösterildiği gibi,
SNAPSHOT
veritabanı seçeneğiniALLOW_SNAPSHOT_ISOLATION
olarak ayarlayarakON
yalıtımı sağlayın.ALTER DATABASE AdventureWorks2022 SET ALLOW_SNAPSHOT_ISOLATION ON;
Veritabanları arası sorgular kullanılırken,
SNAPSHOT
yalıtımı altında çalışan bir işlem,ALLOW_SNAPSHOT_ISOLATION
veritabanı seçeneğininON
olarak ayarlandığı veritabanlarındaki tablolara erişebilir.ALLOW_SNAPSHOT_ISOLATION
veritabanı seçeneğiON
olarak ayarlı olmayan veritabanlarındaki tablolara erişmek için yalıtım düzeyi değiştirilmelidir. Örneğin, aşağıdaki kod örneği birSELECT
işlemi altında çalışırken iki tabloyu birleştiren birSNAPSHOT
deyimini gösterir. Bir tablo,SNAPSHOT
yalıtımının etkinleştirilmediği bir veritabanına aittir.SELECT
deyimiSNAPSHOT
yalıtım altında çalıştırıldığında başarıyla yürütülemiyor.SET TRANSACTION ISOLATION LEVEL SNAPSHOT; BEGIN TRANSACTION; SELECT t1.col5, t2.col5 FROM Table1 as t1 INNER JOIN SecondDB.dbo.Table2 as t2 ON t1.col1 = t2.col2;
Aşağıdaki kod örneği, belirli bir tabloya erişirken işlem yalıtım düzeyini
SELECT
olarak değiştirmek için değiştirilen aynıREAD COMMITTED
deyimini gösterir. Bu değişiklik nedeniyleSELECT
deyimi başarıyla yürütülür.SET TRANSACTION ISOLATION LEVEL SNAPSHOT; BEGIN TRANSACTION; SELECT t1.col5, t2.col5 FROM Table1 as t1 WITH (READCOMMITTED) INNER JOIN SecondDB.dbo.Table2 as t2 ON t1.col1 = t2.col2;
Satır sürüm oluşturma tabanlı yalıtım düzeylerini kullanan işlemlerin sınırlamaları
Satır sürüm oluşturma tabanlı yalıtım düzeyleriyle çalışırken aşağıdaki sınırlamaları göz önünde bulundurun:
READ_COMMITTED_SNAPSHOT
tempdb
,msdb
veyamaster
içinde etkinleştirilemez.Genel geçici tablolar
tempdb
içinde depolanır. birSNAPSHOT
işlemi içindeki genel geçici tablolara erişirken aşağıdakilerden biri gerçekleşmelidir:-
ALLOW_SNAPSHOT_ISOLATION
'daON
içintempdb
veritabanı seçeneğini ayarlayın. - İfadenin izolasyon düzeyini değiştirmek için bir izolasyon ipucu kullanın.
-
SNAPSHOT
işlemler şu durumlarda başarısız olur:- Veritabanı,
SNAPSHOT
işlemi başladıktan sonra ancakSNAPSHOT
işlemi veritabanına erişmeden önce salt okunur hale getirilir. - Birden çok veritabanından nesnelere erişilirse, veritabanı durumu,
SNAPSHOT
bir işlem başlatıldıktan sonra ancakSNAPSHOT
işlemi veritabanına erişmeden önce veritabanı kurtarmanın gerçekleştiği şekilde değiştirildi. Örneğin: veritabanıOFFLINE
ve sonraONLINE
olarak ayarlandı,AUTO_CLOSE
olarak ayarlananON
seçeneği nedeniyle veritabanı otomatik olarak kapatıldı ve yeniden açıldı veya veritabanı ayrıldı ve yeniden eklendi.
- Veritabanı,
Dağıtılmış bölümlenmiş veritabanlarındaki sorgular da dahil olmak üzere dağıtılmış işlemler
SNAPSHOT
yalıtımı altında desteklenmez.Veritabanı Altyapısı, sistem meta verilerinin birden çok sürümünü tutmaz. Tablolar ve diğer veritabanı nesneleri (dizinler, görünümler, veri türleri, saklı yordamlar ve ortak dil çalışma zamanı işlevleri) üzerindeki veri tanımı dili (DDL) deyimleri meta verileri değiştirir. DDL deyimi bir nesneyi değiştirirse,
SNAPSHOT
yalıtımı altındaki nesneye yapılan tüm eşzamanlı başvurularSNAPSHOT
işleminin başarısız olmasına neden olur.READ COMMITTED
veritabanı seçeneğiREAD_COMMITTED_SNAPSHOT
olarak ayarlandığındaON
işlemleri bu sınırlamaya sahip değildir.Örneğin, veritabanı yöneticisi aşağıdaki
ALTER INDEX
deyimini yürütür.USE AdventureWorks2022; GO ALTER INDEX AK_Employee_LoginID ON HumanResources.Employee REBUILD; GO
ALTER INDEX
deyimi yürütülürken etkin olan tüm anlık görüntü işlemleri,HumanResources.Employee
deyimi yürütüldükten sonraALTER INDEX
tablosuna başvurmaya çalışırsa bir hata alır. Satır sürümlemesi kullananREAD COMMITTED
numaralı işlemler etkilenmez.Not
BULK INSERT
işlemleri hedef tablo meta verisinde değişikliklere neden olabilir (örneğin, kısıtlama denetimlerini devre dışı bırakırken). Bu durumda, toplu eklenen tablolara erişen eşzamanlıSNAPSHOT
yalıtım işlemleri başarısız olur.
Kilitlemeyi ve satır sürümlendirmesini özelleştirme
Kilit zaman aşımını özelleştir
Veritabanı Altyapısı örneği, bir işleme kilit veremediğinde, çünkü kaynakta çakışan bir kilidi zaten başka bir işlem tutmaktadır, ilk işlem mevcut kilidin serbest bırakılmasını beklerken engellenir. Varsayılan olarak, kilit beklemeleri için zaman aşımı süresi yoktur, bu nedenle bir işlem potansiyel olarak süresiz olarak engellenebilir.
Not
Bir görevin engellenip engellenmediğini ve neyin engellendiğini belirlemek için sys.dm_os_waiting_tasks
dinamik yönetim görünümünü kullanın. Daha fazla bilgi ve örnek için bkz. SQL Server engelleme sorunlarını anlama ve çözme.
LOCK_TIMEOUT
ayarı, uygulamanın bir deyimin engellenen kaynakta bekleyeceği en uzun süreyi ayarlamasına olanak tanır. Bir deyim LOCK_TIMEOUT
ayarından daha uzun süre beklediğinde engellenen deyim otomatik olarak iptal edilir ve hata iletisi 1222 (Lock request time-out period exceeded
) döndürülür. Ancak bu ifadeyi içeren işlemler geri alınmaz. Bu nedenle, uygulamanın 1222 hata iletisini tuzağa düşürebilen bir hata işleyicisi olmalıdır. Bir uygulama hatayı yakalamazsa, uygulama bir işlem içindeki tek bir deyimin iptal edildiğini ancak işlemin etkin kaldığını fark etmeyecek şekilde devam edebilir. İşlemin sonraki adımları, hiçbir zaman yürütülmemiş bir deyime bağlı olabileceği için hatalar oluşabilir.
Hata iletisi 1222'yi yakalamaya yönelik bir hata işleyicisi uygulamak, uygulamanın zaman aşımı durumunu işlemesine ve şu gibi düzeltici eylemler gerçekleştirmesine olanak tanır: engellenen deyimi otomatik olarak yeniden gönderme veya işlemin tamamını geri alma.
Önemli
Açık işlemler kullanan ve hata 1222'yi aldıktan sonra işlemin sonlandırılabilmesini gerektiren uygulamaların hata işlemenin bir parçası olarak işlemi açıkça geri alması gerekir. Bu olmadan, işlem etkin kalırken diğer deyimler istemeden aynı oturumda yürütülebilir ve işlem daha sonra geri alınırsa ilişkisiz işlem günlüğü büyümesine ve veri kaybına neden olur.
Geçerli LOCK_TIMEOUT
ayarını belirlemek için @@LOCK_TIMEOUT
işlevini yürütür:
SELECT @@LOCK_TIMEOUT;
GO
İşlem yalıtım düzeyini özelleştirme
READ COMMITTED
, Veritabanı Altyapısı için varsayılan yalıtım düzeyidir. Bir uygulamanın farklı bir yalıtım düzeyinde çalışması gerekiyorsa, yalıtım düzeyini ayarlamak için aşağıdaki yöntemleri kullanabilir:
- SET TRANSACTION ISOLATION LEVEL deyimini çalıştırın.
-
System.Data.SqlClient
ad alanını kullanan ADO.NET uygulamalarIsolationLevel
yöntemini kullanarak birSqlConnection.BeginTransaction
seçeneği belirtebilir. - ADO kullanan uygulamalar
Autocommit Isolation Levels
özelliğini ayarlayabilir. - bir işlem başlatırken, OLE DB kullanan uygulamalar istenen işlem yalıtım düzeyine ayarlanmış
ITransactionLocal::StartTransaction
ileisoLevel
çağırabilir. Otomatik komut modunda yalıtım düzeyini belirtirken, OLE DB kullanan uygulamalarDBPROPSET_SESSION
özelliğiniDBPROP_SESS_AUTOCOMMITISOLEVELS
istenen işlem yalıtım düzeyine ayarlayabilir. - ODBC kullanan uygulamalar
SQL_COPT_SS_TXN_ISOLATION
kullanarakSQLSetConnectAttr
özniteliğini ayarlayabilir.
Yalıtım düzeyi belirtildiğinde, oturumdaki tüm sorgular ve veri işleme dili (DML) deyimleri için kilitleme davranışı bu yalıtım düzeyinde çalışır. Yalıtım düzeyi, oturum sonlandırana kadar veya yalıtım düzeyi başka bir düzeye ayarlanana kadar etkin kalır.
Aşağıdaki örnek, SERIALIZABLE
yalıtım düzeyini ayarlar:
USE AdventureWorks2022;
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
GO
BEGIN TRANSACTION;
SELECT BusinessEntityID
FROM HumanResources.Employee;
COMMIT;
GO
Yalıtım düzeyi, gerekirse tek tek sorgu veya DML deyimleri için tablo düzeyi ipucu belirtilerek geçersiz kılınabilir. Tablo düzeyinde ipucunun belirtilmesi oturumdaki diğer deyimleri etkilemez.
Şu anda ayarlanmış olan işlem yalıtım düzeyini belirlemek için aşağıdaki örnekte gösterildiği gibi DBCC USEROPTIONS
deyimini kullanın. Sonuç kümesi, sisteminizdeki sonuç kümesinden farklı olabilir.
USE AdventureWorks2022;
GO
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
GO
DBCC USEROPTIONS;
GO
Sonuç kümesi aşağıdadır.
Set Option Value
---------------------------- -------------------------------------------
textsize 2147483647
language us_english
dateformat mdy
datefirst 7
... ...
Isolation level repeatable read
(14 row(s) affected)
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
İpuçlarını kilitleme
SELECT
, INSERT
, UPDATE
, DELETE
ve MERGE
ifadelerindeki her bir tablo başvurusu için kilitleme ipuçları belirtilebilir. İpuçları, Veritabanı Altyapısı örneğinin tablo verileri için kullandığı kilitleme veya satır sürümü oluşturma türünü belirtir. Tablo düzeyinde kilitleme ipuçları, bir nesne üzerinde alınan kilit türlerinin daha ayrıntılı bir denetimi gerektiğinde kullanılabilir. Bu kilitleme ipuçları oturum için geçerli işlem yalıtım düzeyini geçersiz kılar.
Not
İyileştirilmiş kilitleme etkinleştirildiğinde, kilitleme ipuçlarının kullanılması önerilmez. Tablo ve sorgu ipuçları kabul edilirken, optimize edilmiş kilitlemenin avantajını azaltır. Daha fazla bilgi için bkz. İyileştirilmiş kilitlemelerde kilitleme ipuçlarından kaçınma.
Belirli kilitleme ipuçları ve davranışları hakkında daha fazla bilgi için bkz. Tablo İpuçları (Transact-SQL).
Not
Varsayılan kilitleme davranışını yalnızca gerektiğinde değiştirmek için tablo düzeyinde kilitleme ipuçlarının kullanılmasını öneririz. Kilitleme düzeyini zorlamak eşzamanlılığı olumsuz etkileyebilir.
Veri okurken paylaşılan kilitlere yönelik istekleri engelleyen bir kilitleme ipucuyla bir deyimi işlerken bile Veritabanı Altyapısı'nın meta verileri okurken kilit alması gerekebilir. Örneğin, SELECT
yalıtım düzeyi altında çalışan veya READ UNCOMMITTED
ipucunu kullanan bir NOLOCK
deyimi, verileri okurken paylaşım kilitleri almaz, ancak bazen sistem kataloğu görünümünü okurken kilit isteğinde bulunabilir. Bu, eş zamanlı bir işlem tablonun meta verilerini değiştirirken böyle bir SELECT
deyiminin engellenmesi mümkün olduğu anlamına gelir.
Aşağıdaki örnekte gösterildiği gibi, işlem yalıtım düzeyi SERIALIZABLE
olarak ayarlanırsa ve NOLOCK
deyimiyle tablo düzeyinde kilitleme ipucu SELECT
kullanılırsa, genellikle SERIALIZABLE
işlemleri korumak için kullanılan anahtar aralığı kilitleri alınmaz.
USE AdventureWorks2022;
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
GO
BEGIN TRANSACTION;
GO
SELECT JobTitle
FROM HumanResources.Employee WITH (NOLOCK);
GO
-- Get information about the locks held by
-- the transaction.
SELECT resource_type,
resource_subtype,
request_mode
FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID;
-- End the transaction.
ROLLBACK;
GO
HumanResources.Employee
referans alan elde edilmiş tek kilit, bir şema kararlılığı (Sch-S
) kilididir. Bu durumda seri hale getirilebilirlik artık garanti değildir.
LOCK_ESCALATION
seçeneği, ALTER TABLE
'de kilit yükseltmesi sırasında tablo kilitlerini önler ve bölümlenmiş tablolarda HoBT (bölüm) kilitlerini etkinleştirir. Bu seçenek bir kilitleme ipucu değildir ve kilit yükseltmesini azaltmak için kullanılabilir. Daha fazla bilgi için bkz. ALTER TABLE (Transact-SQL).
Dizin için kilitlemeyi özelleştir
Veritabanı Altyapısı, çoğu durumda sorgular için en iyi kilitleme ayrıntı düzeyini otomatik olarak seçen bir dinamik kilitleme stratejisi kullanır. Tablo veya dizin erişim desenleri iyi anlaşılmadığı ve tutarlı olmadığı ve çözülmesi gereken bir kaynak çekişmesi sorunu olmadığı sürece varsayılan kilitleme düzeylerini geçersiz kılmamanızı öneririz. Kilitleme düzeyini geçersiz kılma, tablo veya dizine eşzamanlı erişimi önemli ölçüde engelleyebilir. Örneğin, kullanıcıların yoğun olarak eriştiği büyük bir tabloda yalnızca tablo düzeyi kilitlerin belirtilmesi performans sorunlarına neden olabilir çünkü kullanıcıların tabloya erişmeden önce tablo düzeyinde kilidin serbest bırakılabilmesini beklemesi gerekir.
Erişim desenleri iyi anlaşılmış ve tutarlıysa, sayfa veya satır kilitlemeye izin vermemenin yararlı olabileceği birkaç durum vardır. Örneğin, bir veritabanı uygulaması toplu işlemde haftalık olarak güncelleştirilen bir arama tablosu kullanır. Eş zamanlı okuyucular tabloya paylaşılan (S
) bir kilitle erişir ve haftalık toplu güncelleştirme tabloya özel (X
) bir kilitle erişir. Tablodaki sayfa ve satır kilitlemeyi kapatmak, okuyucuların paylaşılan tablo kilitleri aracılığıyla tabloya eşzamanlı olarak erişmesine izin vererek hafta boyunca kilitleme ek yükünü azaltır. Toplu iş çalıştırıldığında, özel tablo kilidi aldığı için güncelleştirmeyi verimli bir şekilde tamamlayabilir.
Sayfa ve satır kilitlemenin kapatılması, haftalık toplu güncelleştirme sırasında güncelleme çalışırken eşzamanlı okuyucuların tabloya erişimini engellediğinden kabul edilebilir veya edilemeyebilir. Toplu iş süreci yalnızca birkaç satır veya sayfayı değiştiriyorsa, diğer oturumların tablodan engelleme olmadan okumasını mümkün kılacak şekilde satır veya sayfa düzeyinde kilitleme iznini ayarlayabilirsiniz. Toplu işin çok sayıda güncelleştirmesi varsa, toplu işin verimli bir şekilde çalıştığından emin olmanın en iyi yolu tabloya münhasır bir kilit koymak olabilir.
Bazı iş yüklerinde, aynı tabloda satır kilitleri edinen iki eşzamanlı işlem, her ikisi de sayfayı kilitlemeye çalıştığında birbirlerini engelleyerek bir kilitlenmeye yol açabilir. Satır kilitlerine izin vermemek, işlemlerden birinin beklemesine neden olur ve böylece kilitlenmeyi önler. Kilitlenmeler hakkında daha fazla bilgi için Kilitlenmeler kılavuzuna bakın.
Dizinde kullanılan kilitlemenin ayrıntı düzeyi, CREATE INDEX
ve ALTER INDEX
deyimleri kullanılarak ayarlanabilir. Ayrıca CREATE TABLE
ve ALTER TABLE
deyimleri, PRIMARY KEY
ve UNIQUE
kısıtlamaları üzerinde kilitleme ayrıntı düzeyini ayarlamak için kullanılabilir. Geriye dönük uyumluluk için sp_indexoption
sistem saklı yordamı da ayrıntı düzeyini ayarlayabilir. Belirli bir dizin için geçerli kilitleme seçeneğini görüntülemek için INDEXPROPERTY
işlevini kullanın. Belirli bir dizin için sayfa düzeyi kilitlere, satır düzeyi kilitlere veya hem sayfa düzeyi hem de satır düzeyi kilitlere izin verilmiyor olabilir.
İzin verilmeyen kilitler | Şu şekilde erişilen dizin: |
---|---|
Sayfa düzeyi | Satır düzeyi ve tablo düzeyi kilitler |
Satır düzeyi | Sayfa düzeyi ve tablo düzeyinde kilitler |
Sayfa düzeyi ve satır düzeyi | Tablo düzeyinde kilitler |
Gelişmiş işlem bilgileri
İç içe işlemler
Açıkça belirlenmiş işlemler iç içe yerleştirilebilir. Bu, asıl amacı, zaten bir işlem içinde bulunan bir süreçten veya etkin işlemi olmayan süreçlerden çağrılabilen saklı yordamlardaki işlemleri desteklemektir.
Aşağıdaki örnekte iç içe işlemlerin kullanımı gösterilmektedir. Eğer bir işlem aktif olduğunda TransProc
çağrılırsa, TransProc
iç içe işlem sonucu, dış işlem tarafından kontrol edilir ve INSERT
deyimleri, dış işlemin gerçekleştirilmesine veya geri alınmasına göre gerçekleştirilir veya geri alınır.
TransProc
açık işlemi olmayan bir süreç tarafından yürütülürse, prosedürün sonundaki COMMIT TRANSACTION
INSERT
deyimlerini tamamlar.
SET QUOTED_IDENTIFIER OFF;
GO
SET NOCOUNT OFF;
GO
CREATE TABLE TestTrans
(
ColA INT PRIMARY KEY,
ColB CHAR(3) NOT NULL
);
GO
CREATE PROCEDURE TransProc
@PriKey INT,
@CharCol CHAR(3)
AS
BEGIN TRANSACTION InProc;
INSERT INTO TestTrans VALUES (@PriKey, @CharCol);
INSERT INTO TestTrans VALUES (@PriKey + 1, @CharCol);
COMMIT TRANSACTION InProc;
GO
/* Start a transaction and execute TransProc. */
BEGIN TRANSACTION OutOfProc;
GO
EXEC TransProc 1, 'aaa';
GO
/* Roll back the outer transaction, this will
roll back TransProc's nested transaction. */
ROLLBACK TRANSACTION OutOfProc;
GO
EXECUTE TransProc 3,'bbb';
GO
/*
The following SELECT statement shows only rows 3 and 4 are
still in the table. This indicates that the commit
of the inner transaction from the first EXECUTE statement of
TransProc was overridden by the subsequent roll back of the
outer transaction.
*/
SELECT *
FROM TestTrans;
GO
Veritabanı Altyapısı, dış işlem aktifken iç işlemleri yok sayar. İşlem, en dıştaki işlemin sonundaki işleme bağlı olarak ya onaylanır ya da geri alınır. Dış işlem onaylanırsa, iç içe geçmiş işlemler de onaylanır. Dış işlem geri alınırsa, iç işlemlerin ayrı ayrı işlenip işlenmediğine bakılmaksızın tüm iç işlemler de geri alınır.
Her COMMIT TRANSACTION
veya COMMIT WORK
çağrısı, son yürütülen BEGIN TRANSACTION
için geçerlidir.
BEGIN TRANSACTION
deyimleri iç içe yerleştirilmişse, COMMIT
deyimi yalnızca en iç içe geçen işlem olan son iç içe işleme uygulanır. İç içe geçmiş bir işlemdeki COMMIT TRANSACTION transaction_name
deyimi, dış işlemin işlem adına başvursa bile, yalnızca en içteki işleme onay uygulanır.
bir transaction_name
deyiminin ROLLBACK TRANSACTION
parametresinin adlandırılmış iç içe işlemler kümesindeki iç işleme başvurmasına izin verilmez.
transaction_name
yalnızca en dıştaki işlemin adına atıfta bulunabilir. Dış işlemin adını kullanan bir ROLLBACK TRANSACTION transaction_name
deyimi iç içe işlemler kümesinin herhangi bir düzeyinde yürütülürse, iç içe işlemlerin tümü geri alınır.
ROLLBACK WORK
parametresi olmayan bir ROLLBACK TRANSACTION
veya transaction_name
deyimi iç içe bir işlem kümesinin herhangi bir düzeyinde yürütülürse, en dıştaki işlem de dahil olmak üzere iç içe tüm işlemleri geri alır.
@@TRANCOUNT
işlevi geçerli işlem iç içe yerleştirme düzeyini kaydeder. Her BEGIN TRANSACTION
deyimi, @@TRANCOUNT
'i bir artırır. Her COMMIT TRANSACTION
veya COMMIT WORK
deyimi, @@TRANCOUNT
'yi bir azaltır. İşlem adı olmayan bir ROLLBACK WORK
veya ROLLBACK TRANSACTION
deyimi, tüm iç içe geçmiş işlemleri geri alır ve @@TRANCOUNT
'yi 0'a düşürür. En içteki işlem kümesinde en dıştaki işlemin adını kullanan bir ROLLBACK TRANSACTION
, tüm iç içe işlemleri geri alır ve @@TRANCOUNT
'i 0'a indirir. İşlemde olup olmadığınızı belirlemek için SELECT @@TRANCOUNT
'ın 1 veya daha fazla olup olmadığını kontrol edin.
@@TRANCOUNT
0 ise, bir işlemde olmazsınız.
Bağlı oturumları kullanma
Bağlı oturumlar, aynı sunucudaki birden çok oturumdaki eylemlerin koordinasyonunu kolaylaştırır. Bağlantılı oturumlar, iki veya daha fazla oturumun aynı işlemi ve kilitleri paylaşmasına olanak sağlar ve kilit çakışması olmadan aynı veriler üzerinde çalışabilir. İlişkili oturumlar, aynı uygulama içindeki birden çok oturumdan veya ayrı oturumlara sahip birden çok uygulamadan oluşturulabilir.
Bağlı bir oturuma katılmak için, bir oturum bağlama belirteci almak üzere (Open Data Services aracılığıyla) sp_getbindtoken veya srv_getbindtoken çağırır. Bağlama belirteci, her ilişkili işlemi benzersiz olarak tanımlayan bir karakter dizesidir. Bağlama belirteci daha sonra geçerli oturumla ilişkilendirilmesi için diğer oturumlara gönderilir. Diğer oturumlar, ilk oturumdan alınan bağlama belirtecini kullanarak sp_bindsession
çağrısı yaparak işleme bağlanır.
Not
sp_getbindtoken
veya srv_getbindtoken
başarılı olması için oturumun etkin bir kullanıcı işlemi olması gerekir.
Bağlama belirteçleri, ilk oturumu yapan uygulama kodundan daha sonra oturumlarını ilk oturuma bağlayan uygulama koduna iletilmelidir. Bir uygulamanın başka bir işlem tarafından başlatılan bir işlemin bağlama belirtecini almak için kullanabileceği Transact-SQL deyimi veya API işlevi yoktur. Bağlama belirtecini iletmek için kullanılabilecek yöntemlerden bazıları şunlardır:
Oturumların tümü aynı uygulama işleminden başlatılırsa, bağlama belirteçleri genel bellekte depolanabilir veya bir parametre olarak işlevlere geçirilebilir.
Oturumlar ayrı uygulama işlemlerinden yapılırsa, bağlama belirteçleri uzaktan yordam çağrısı (RPC) veya dinamik veri değişimi (DDE) gibi işlemler arası iletişim (IPC) kullanılarak iletilebilir.
Bağlama belirteçleri, ilk oturuma bağlamak isteyen işlemler tarafından okunabilen Veritabanı Altyapısı örneğindeki bir tabloda depolanabilir.
Bir dizi ilişkili oturumda herhangi bir anda yalnızca bir oturum etkin olabilir. Bir oturum örnekte bir deyim yürütüyorsa veya örnekten bekleyen sonuçlar varsa, geçerli oturum işlemeyi bitirene veya geçerli deyimi iptal edene kadar aynı belirteçle ilişkili başka bir oturum örneğe erişemez. Örnek, ilişkili oturumların başka birindeki bir deyimi işlemekle meşgulse, işlem alanının kullanımda olduğunu ve oturumun daha sonra yeniden denemesi gerektiğini belirten bir hata oluşur.
Oturumları bağladığınızda, her oturum yalıtım düzeyi ayarını korur. Bir oturumun yalıtım düzeyi ayarını değiştirmek için SET TRANSACTION ISOLATION LEVEL
kullanılması, aynı belirteçle ilişkili başka bir oturumun ayarını etkilemez.
Bağlı oturum türleri
İki bağlı oturum türü yerel ve dağıtılmıştır.
Yerel bağlı oturum Bağlı oturumların veritabanı altyapısının tek bir örneğinde tek bir işlemin işlem alanını paylaşmasına izin verir.
Dağıtılmış bağlı oturum Tüm işlem Microsoft Dağıtılmış İşlem Düzenleyicisi (MS DTC) kullanılarak işlenene veya geri alınana kadar bağlı oturumların aynı işlemi iki veya daha fazla örnekte paylaşmasına izin verir.
Dağıtılmış bağlı oturumlar bir karakter dizesi bağlama belirteci tarafından tanımlanmaz; dağıtılmış işlem kimlik numaralarıyla tanımlanırlar. Bağlı bir oturum yerel bir işleme dahil edilirse ve SET REMOTE_PROC_TRANSACTIONS ON
ile uzak sunucuda rpc yürütürse, yerel ilişkili işlem otomatik olarak MS DTC tarafından dağıtılmış bir bağlı işleme yükseltilir ve bir MS DTC oturumu başlatılır.
Bağlı oturumları ne zaman kullanmalıyız?
SQL Server'ın önceki sürümlerinde, ilişkili oturumlar öncelikli olarak onları çağıran işlem adına Transact-SQL deyimlerini yürütmesi gereken genişletilmiş saklı yordamların geliştirilmesinde kullanılıyordu. Arama işleminin genişletilmiş saklı yordamın bir parametresi olarak bağlama belirtecini geçirmesi, yordamın çağrı işleminin işlem alanını birleştirmesini sağlar ve böylece genişletilmiş saklı yordamı çağırma işlemiyle tümleştirir.
Veritabanı Altyapısı'nda, CLR kullanılarak yazılan saklı yordamlar genişletilmiş saklı yordamlara göre daha güvenli, ölçeklenebilir ve kararlıdır. CLR saklı yordamları, çağıran oturumun bağlamını birleştirmek için SqlContext
değil, sp_bindsession
nesnesini kullanır.
İlişkili oturumlar, iş mantığının tek bir işlemsel süreç üzerinde uyumlu çalışan ayrı programlara dahil olduğu üç katmanlı uygulamalar geliştirmek için kullanılabilir. Bu programların veritabanına erişimini dikkatle koordine etmek için kodlanması gerekir. İki oturum aynı kilitleri paylaştığından, iki program aynı anda aynı verileri değiştirmeye çalışmamalıdır. Herhangi bir zamanda, işlemin bir parçası olarak yalnızca bir oturum iş yapabilir; paralel yürütme mümkün değildir. İşlem yalnızca tüm DML deyimlerinin tamamlanıp sonuçlarının alınması gibi iyi tanımlanmış verim noktalarındaki oturumlar arasında geçiş yapılabilir.
Verimli işlemler için kod yazma
İşlemlerin olabildiğince kısa tutulması önemlidir. bir işlem başlatıldığında, işlemin bölünmezliği, tutarlılığı, yalıtımı ve dayanıklılık (ACID) özelliklerini korumak için bir veritabanı yönetim sisteminin (DBMS) işlemin sonuna kadar birçok kaynak tutması gerekir. Veriler değiştirilirse, değiştirilen satırlar, diğer işlemlerin satırları okumasını engelleyen özel kullanım kilitleriyle korunmalıdır ve işlem işlenene veya geri alınana kadar özel kilitler tutulmalıdır. İşlem yalıtım düzeyi ayarlarına bağlı olarak, SELECT
deyimleri kilitler alabilir ve bu kilitler, işlem tamamlanana ya da geri alınıncaya kadar tutulmalıdır. Özellikle çok sayıda kullanıcısı olan sistemlerde eşzamanlı bağlantılar arasındaki kaynakların kilitlenme çekişmesini azaltmak için işlemler mümkün olduğunca kısa tutulmalıdır. Uzun süre çalışan, verimsiz işlemler az sayıda kullanıcıyla ilgili bir sorun olmayabilir, ancak binlerce kullanıcının olduğu bir sistemde son derece sorunludur. SQL Server 2014 (12.x) sürümünden itibaren Veritabanı Altyapısı gecikmeli dayanıklı işlemleri destekler. Gecikmeli dayanıklı işlemler ölçeklenebilirliği ve performansı geliştirebilir, ancak dayanıklılığı garanti etmez. Daha fazla bilgi için bkz. İşlem Dayanıklılığını Denetleme.
Kod yönergeleri
Verimli işlemleri kodlama yönergeleri şunlardır:
İşlem sırasında kullanıcıların girişini gerektirmez. İşlem başlatılmadan önce kullanıcılardan tüm gerekli girişleri alın. bir işlem sırasında ek kullanıcı girişi gerekiyorsa, geçerli işlemi geri alın ve kullanıcı girişi sağlandıktan sonra işlemi yeniden başlatın. Kullanıcılar hemen yanıt verse bile, insan tepki süreleri bilgisayar hızlarından çok daha yavaştır. İşlem tarafından tutulan tüm kaynaklar, çok uzun süre boyunca elde tutulur ve bu durum engelleme sorunlarına yol açabilir. Kullanıcılar yanıt vermezse işlem etkin kalır ve kritik kaynakları yanıt verene kadar kilitler ve bu işlem birkaç dakika hatta saatler boyunca gerçekleşmeyebilir.
Mümkünse, verilere göz atarken bir işlemi açmayın. Tüm ön veri analizi tamamlanana kadar işlemler başlatılmamalıdır.
İşlemi olabildiğince kısa tutun. Yapılması gereken değişiklikleri anladıktan sonra bir işlem başlatın, değişiklik ifadelerini yürütün ve ardından hemen işlemi onaylayın veya geri alın. gerekli olmadan önce işlemi açmayın.
Engellemeyi azaltmak için, salt okunur sorgular için satır sürümlendirmesi tabanlı bir yalıtım düzeyi kullanmayı göz önünde bulundurun.
Daha düşük işlem yalıtım düzeylerini akıllı bir şekilde kullanın. Birçok uygulama,
READ COMMITTED
işlem yalıtım düzeyini kullanacak şekilde kodlanabilir. Çok az işlem,SERIALIZABLE
işlem yalıtım düzeyini gerektirir.İyimser eşzamanlılık seçeneklerini akıllı bir şekilde kullanın. Eşzamanlı güncelleştirme olasılığının düşük olduğu bir sistemde, ara sıra karşılaşılabilecek "siz okuduktan sonra başka biri verilerinizi değiştirdi" hatasıyla başa çıkmanın yükü, satırları okurken her zaman kilitlemekten çok daha az olabilir.
İşlem sırasında mümkün olan en az miktarda veriye erişin. Bu, kilitli satır sayısını azaltır ve böylece işlemler arasındaki çekişme azalır.
Mümkün olduğunca
HOLDLOCK
gibi kötümser kilitleme ipuçlarından kaçının.HOLDLOCK
veyaSERIALIZABLE
yalıtım düzeyi gibi ipuçları, işlemlerin paylaşılan kilitlerde bile beklemesine ve eşzamanlılığı azaltmasına neden olabilir.Mümkün olduğunda örtük işlemler kullanmaktan kaçının. Örtük işlemler, doğası gereği öngörülemeyen davranışlara neden olabilir. Bkz. Örtük İşlemler ve eşzamanlılık sorunları.
Örtük işlemler ve eşzamanlılık ve kaynak sorunlarından kaçınma
Eşzamanlılık ve kaynak sorunlarını önlemek için örtük işlemleri dikkatle yönetin. Örtük işlemleri kullanırken, COMMIT
veya ROLLBACK
sonraki Transact-SQL deyimi otomatik olarak yeni bir işlem başlatır. Bu, uygulama verilere göz atarken veya kullanıcıdan giriş gerektirdiğinde bile yeni bir işlemin açılmasına neden olabilir. Veri değişikliklerini korumak için gereken son işlemi tamamladıktan sonra, veri değişikliklerini korumak için bir kez daha gerekli hale gelene kadar örtük işlemleri kapatın. Bu işlem, uygulama verilere göz atarken ve kullanıcıdan giriş alırken Veritabanı Altyapısı'nın otomatik komut modunu kullanmasına olanak tanır.
Ayrıca, SNAPSHOT
yalıtım düzeyi etkinleştirildiğinde, yeni bir işlem kilitleri tutmasa da, uzun süre çalışan bir işlem eski sürümlerin sürüm deposundan kaldırılmasını engeller.
Uzun süre çalışan işlemleri yönetme
uzun süre çalışan işlem, zamanında işlenmemiş veya geri alınmamış etkin bir işlemdir. Örneğin, bir işlemin başlangıcı ve sonu kullanıcı tarafından denetleniyorsa, uzun süre çalışan bir işlemin tipik bir nedeni, kullanıcının bir işlem başlatması ve ardından işlem kullanıcıdan yanıt beklerken ayrılmasıdır.
Uzun süre çalışan bir işlem, aşağıdaki gibi bir veritabanı için ciddi sorunlara neden olabilir:
Etkin bir işlem çok sayıda kaydedilmemiş değişiklik yaptıktan sonra sunucu örneği kapatılırsa, sonraki yeniden başlatmanın kurtarma aşaması
recovery interval
sunucu yapılandırma seçeneği veyaALTER DATABASE ... SET TARGET_RECOVERY_TIME
seçeneği tarafından belirtilen süreden çok daha uzun sürebilir. Bu seçenekler sırasıyla etkin ve dolaylı denetim noktalarını denetler. Denetim noktası türleri hakkında daha fazla bilgi için bkz. Veritabanı denetim noktaları (SQL Server).Daha da önemlisi, bekleyen bir işlem (transaction) çok az kayıt oluştursa da, kayıt kısıtlamasını süresiz olarak engeller ve işlem kayıtlarının büyümesine ve belki de dolmasına neden olur. İşlem günlüğü dolarsa veritabanı daha fazla yazma işlemi gerçekleştiremez. Daha fazla bilgi için bkz. SQL Server işlem günlüğü mimarisi ve yönetim kılavuzu, tam işlem günlüğü (SQL Server Hatası 9002) sorunlarını giderme ve İşlem günlüğü.
Önemli
Azure SQL Veritabanı'nda boştaki işlemler (altı saat boyunca işlem günlüğüne yazılmayan işlemler) otomatik olarak sonlandırılarak kaynaklar serbest kalır.
Uzun süreli işlemleri keşfetme
Uzun süre çalışan işlemleri aramak için aşağıdakilerden birini kullanın:
sys.dm_tran_database_transactions
Bu dinamik yönetim görünümü, veritabanı düzeyindeki işlemler hakkında bilgi döndürür. Uzun süre çalışan bir işlem için, belirli bir ilgi alanına sahip sütunlar ilk günlük kaydının zamanını (
database_transaction_begin_time
), işlemin geçerli durumunu (database_transaction_state
) ve kaydı başlatır.Daha fazla bilgi için bkz. sys.dm_tran_database_transactions (Transact-SQL).
DBCC OPENTRAN
Bu deyim, işlemin sahibinin kullanıcı kimliğini belirlemenize olanak tanır, böylece uygun sonlandırma (işleme veya geri alma) için işlemin kaynağını izleyebilirsiniz. Daha fazla bilgi için bkz. DBCC OPENTRAN (Transact-SQL) .
İşlemi sonlandırma
Belirli bir oturumdaki bir işlemi sonlandırmak için KILL
deyimini kullanın. Ancak, özellikle kritik işlemler çalışırken bu deyimi çok dikkatli kullanın. Daha fazla bilgi için bkz. KILL (Transact-SQL).
Kilitlenmeler
Kilitlenmeler, kilitlemeyle bağlantılı karmaşık bir konudur, fakat engellemeden farklıdır.
- İzleme, tanılama ve örnekler de dahil olmak üzere kilitlenmeler hakkında daha fazla bilgi için Kilitlenmeler kılavuzuna bakın.
- Azure SQL Veritabanı'na özgü kilitlenmeler hakkında daha fazla bilgi için bkz. Azure SQL Veritabanı'nda kilitlenmeleri analiz etme ve önleme.