TRANSACTION etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
TRANSACTION etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

29 Ekim 2010 Cuma

TRY - CATCH ve TRANSACTION kullanımı

Try Catch yapısını, transactionlar ile kullanmak hem yapılan kontrol sayısını azaltır, hem de daha anlaşılır bir kod yazmanızı sağlar.

Try Catch kullanılmazsa (SQL 2005 öncesi versiyonlarda zaten try catch olmadığı için mecburan) her bir statementdan sonra @@Error den gelen hata kodunu bir değişkene atmanız, bir sorun varsa rollback yoksa kodun devam etmesi veya commit etmesi için if cümleleri ile uğraşmanız gerekir. 

TRY/CATCH ile hataları yönetmek ve transactionlar ile çalışmak daha da kolaylaştı.
İşte birkaç örnek.

DECLARE @ErrorNumber int = 0 , @ErrorMessage nvarchar(max)

BEGIN TRANSACTION
BEGIN TRY

END TRY
BEGIN CATCH

SELECT @ErrorNumber = ERROR_NUMBER(), @ErrorMessage = ERROR_MESSAGE()
END CATCH

IF @ErrorNumber<>0
ROLLBACK TRANSACTION
ELSE
COMMIT TRANSACTION


-------------------------------


DECLARE @ErrorNumber int = 0 , @ErrorMessage nvarchar(max)

BEGIN TRANSACTION
BEGIN TRY

  COMMIT TRANSACTION
END TRY
BEGIN CATCH
    SELECT @ErrorNumber = ERROR_NUMBER(), @ErrorMessage = ERROR_MESSAGE()
    IF @@TRANCount>0 ROLLBACK TRANSACTION
END CATCH

İsimlendirilmiş Transactionlar

İsimlendirilmiş transactionlar, bir transactiona belli bir isim atanmış transactionlardır. İçiçe transactionlar ile çalışıldığında, hangi transactionın, ne durumda olduğunu bulabilirsiniz. Ayrıca lockları izlemek kolaylaşır, hangi transaction uzun süreli locklara neden olduğu tespit edilebilir.

BEGIN TRANSACTION myTranName


-- Transaction içinde çalışacak kodlar. 


COMMIT TRANSACTION myTranName

şeklinde kullanılır.

Transactiona verilen isim, SQL Server'ın objelere isim verme kurallarına uygun olmalıdır ve 32 karakterden uzun olamaz.

TRANSACTION Türleri

SQL Server 2 tür transaction yapısını destekler.
Local Transaction : Aynı server üzerinde kalan transactionlardır. BEGIN TRANSACTION veya daha kısa yazımıyla BEGIN TRAN ifadesi ile başlatırlar.

Distributed Transaction : BEGIN DISTRIBUTED TRANSACTION veya BEGIN DISTRIBUTED TRAN ifadesi ile başlatırlar. Bu tür transaction türleri, eğer bir transaction içerisinde server dışına çıkılacak ise kullanılır. Bu daha çok bir query, linked server ile başka bir servera bağlanıyorsa veya OPENROWSET kullanılıyorsa oluşur. Bu transactionlar sadece SQL Server için değil, distributed transaction yapısını destekleyen Oracle, DB2 gibi veri tabanlarına bağlanılıyorsa da kullanılabilir.

Transactionlar Hakkında Doğru Bilinen Yanlışlar

 Eğer transaction içerisinde bir komut hata verirse, diğer komutların dataları da işlenmez. 
 Eğer bir hata yakalama mekanizması kullanmadıysanız ve hata durumunda rollback yapmadıysanız, commit cümlesi çalıştığında sorun olmayan komutlar çalışır ve işlemlerini yaparlar.

Bir stored procedure zaten bir transaction dır. 
Bir prosedür içerisindeki her bir kod tek başına bir transaction dır.  Aslında bu stored procedure içinde olmasa da, tüm yazılan insert, update ve delete kodları otomatik commit edilen bir transaction olarak çalışırlar. Ancak stored procedure kodunun tümü tek bir transaction değildir.  Eğer bir stored procedure, tek bir transaction olarak çalıştırılmak isteniyorsa, Begin Transaction ve Commit Transaction bloğu içine yazılmalıdır.  Ancak unutmamak gerekir ki, transaction isolation levela göre bu tablolarda uzun süreli lock oluşmasına, bu arada diğer kullanıcıların hiç bir işlem yapamamasına neden olabilir.

Bir transaction yaratılırsa ve bu transaction içinde bir select ifadesi çalıştırılırsa, kimse select ile çekilen satırlara ulaşamaz. 
 Bu transaction isolation level'a göre doğru da olabilir, yanlış da. Bunun için Transaction Isolation Level ile ilgili yazıma bakabilirsiniz.

Transaction nedir?

Transaction, bir veri tabanına aynı anda işlenen (commit)  veya işlenmesi geri alınabilen (rollback) bir grup komuttur.
Transaction yapısı ile farklı tablolara kayıt ekleyebilir, güncelleme yapabilir veya kayıt silebiliriz ve bu işlemlerden herhangi birinde bir sorun olursa, tüm yapılan işlemleri geri alabiliriz.
Transaction sırasında, tablolar üzerinde olabilecek lock ları, transaction isolation level'ını değiştirerek kontrol edebiliriz.

26 Ekim 2010 Salı

Transaction Isolation Level lar nedir?

SQL Server'da verilerimizi güncellerken, diğer transaction ların verilere nasıl ulaşacağı, lock ların nasıl ve na kadar süre tutulacağı, verilerin nasıl okunacağı  "transaction isolation level" ile karar verilir.

Isolation için   eş zamanlı olarak veri güncellemesi yapan transactionların etkilerinden, diğer transactionları koruma yeteneğidir diyebiliriz.
Her transaction, transaction tamamlanana kadar, güncellen veriyi kilitler.  Veri okuma işlemlerinde, "transaction isolation levels", diğer transaction lar tarafından yapılan değişikliklerin etkilerinden koruma seviyeleridir.

Daha düşük seviye bir isolation level seçilirse, aynı anda birçok kullanıcı veriyer ulaşabilir ancak okunan veriler tutarlı veya güncel olmayabilir.
Yüksek seviye bir isolation level, okunan verinin tutarlılığını arttırken, bir transaction'ın başka transaction ları kilitlemesine neden olabilir.
Veri tutarlılığının üç temel yan etkisi vardır. 
  dirty read :  Bir transaction tarafından bir veri güncellenirken verinin okunmasıdır ve veri güncel olmayabilir
  nonrepeatable read: Bir başka transaction, aynı satırı birçok kez okur ve her seferinde başka bir veri okursa oluşur.
  phantom read : Bir silme veya yeni kayıt ekleme işlemi sırasında, aynı anda okuma işlemi yapılıyorsa ve bu kayıtlar da okunan kayıt setinin içerisindeyse oluşur.  Bu kullanıcının kayıtları eklemediğini düşünmesine ve ikince kez kayıt eklemeye çalışmasına neden olabilir.

En üst seviye isolation "SERIALIZABLE" dır. Tüm transaction her zaman aynı datayı alırlar ancak çok kullanıcılı sistemlerde, bir kullanıcının yaptığı işlem, diğer kullanıcıların işlemlerini etkiler. 

En alt seviye isolation ise "READ UNCOMMITTED" dır.  Diğer transactionlar tarafından güncellenmeye başlamış, ancak henüz commit işlemi tamamlanmamış veriler okunabilir.


READ UNCOMMITTED Başka transactionlardan tarafından güncellenmekte olan, ancak henüz güncelleme işlemleri tamamlanmamış veriler okunabilir.

READ COMMITTED  Başka transactionlar tarafından güncellenmekte olan veriler, güncelleme işlemi tamamlanana kadar okunamazlar.  Bu "dirty read" i engeller.  Veri, her bir transaction arasında başka bir transaction tarafından güncellenebilir. Bu seviyede nonrepeatable veya phantom read ler oluşabilir.
READ COMMITTED seviyesi, SQL Server'ın varsayılan isolation seviyesidir. 

REPEATABLE READ Güncellenen ancak henüz commit edilmeyen veriler, commit edilene kadar okunamaz veya başka transaction lar tarafından güncellenemez.

SNAPSHOT Veri herhangi bir zamanda okunabilir.  Okuma işlemi başladığında verinin son hali ne ise, o veri okunur.  Okuma için başlayan transaction, sadece başlamadan önce commit edilmiş verileri farkeder. Transaction başladıktan sonra başka bir transaction veriyi güncellerse, bu güncellemeleri görmez. 

SERIALIZABLE  Commit edilmemiş veri okunamaz veya güncellenemez. Bir transaction, okunan veri aralığına ait key ile, okuma işlemi tamamlanana kadar insert işlemi yapamaz.