ADO nesnesinde transaction seçimi hk.

MS SQL Server veritabanı ve SQL komutlarıyla ilgli sorularınızı sorabilirsiniz. Delphi tarafındaki sorularınızı lütfen Programlama forumunda sorunuz.
Cevapla
omurolmez
Üye
Mesajlar: 187
Kayıt: 31 Eki 2012 11:41

ADO nesnesinde transaction seçimi hk.

Mesaj gönderen omurolmez »

Merhaba arkadaşlar,

Delphi XE4 dbGo ADO query nesnesi ile, MsSql 2008 R2 üzerinde bazı tablolara insert ve update yapıyorum. Tüm işlemleri, connection nesnesinin BeginTransact metodunu başlattıktan sonra yapıyorum ve tüm işlemler hatasız tamamlandıysa, connection nesnesinin CommitTrans metodunu çağırıyorum.

connection.BeginTrans çağrısından sonra, bir tabloya (mesela adı Tablo1 olsun) insert/update işlemleri yaparken; aynı anda Management Studio 'dan

Kod: Tümünü seç

select * from Tablo1
sorgusu çalıştırmak istediğimde, sorgu askıda kalıyor ve connection.CommitTrans çağrısından önce hiçbir sonuç döndürmüyor. Management STudio 'da Tablo1 'in, programda BeginTrans çağrısı yapmadan önceki halini görebileceğim transaction tipi hangisidir ve bunu ADO üzerinde nasıl ayarlayabilirim ?

İlgilenen arkadaşlara şimdiden teşekkürler ...

Düzenleme:

Ms Sql Server 2008 R2

Bir A programı ADO üzerinden bağlanıyor ve connection.BeginTrans yapıyor. Daha sonra insert into Tablo1 .... yapıyor.
Bir B kullanıcısı Management Studio üzerinden bağlanıyor ve select * from Tablo1 yapıyor. Bu sorgu sonucu, A programını bekliyor ve A programı CommitTrans yapmadan, Management Studio sonuç göstermiyor. Benim istediğim bu sorgu hemen dönsün ve boş tablo göstersin. Çünki, A programı BeginTrans çağırdığı sırada Tablo1 tablosu boştu (Ve henüz ne olacağı belli değil çünki belki de A programı RollbackTrans çağıracak).

Düzenleme:
Arkadaşlar, Google dan bulabildiğim kadarıyla repeteable read, snapshot veya serializable isolation level den birini ve/veya optimistic lock kullanmam gerekiyormuş. Bazı testler yaptıktan sonra, sonucu yazacağım.
Ömür Ölmez
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: ADO nesnesinde transaction seçimi hk.

Mesaj gönderen sabanakman »

ADO bileşenlerine çok kapsamlı özellikler olmadığı için bunu sorgu ile halledebilirsiniz. Başlatılan ve değişen bir tablonun o "transaction" anındaki kayıtları için sorguya ek olarak yazılacak bir parametre kodu ile erişebilirsiniz.

Kod: Tümünü seç

select * from Tablo1 WITH (NOLOCK)
sorgusu o anda değiştirilen tablonun değiştirilmiş son durmundaki kayıt listesini verecektir. Daha kapsamlı bilgi elde etmek için
:ara isolation level dirty read :mrgreen:
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
omurolmez
Üye
Mesajlar: 187
Kayıt: 31 Eki 2012 11:41

Re: ADO nesnesinde transaction seçimi hk.

Mesaj gönderen omurolmez »

Cevabınız için teşekkür ederim Şaban Bey.

Soruyu sorarken, gereksiz ayrıntılarla metni uzatmamayı hedeflemiştim ancak doğru düşünmemişim. Şöyle ki, Ado ile bağlanan program, bizim yazdığımız ve Firebird vt deki tabloların ayna görüntüsünü, başka bir erp firmasının ms sql veritabanında oluşturmaya yarıyor. Dolayısıyla, Dirty Read ile okuma yapma vb şansımız yok. Bize ikinci bir veritabanı açtılar. Büyük ihtimalle kendi veritabanları ile linked server oluşturacaklar. Tahminim daha sonra da bizim tablolarımıza insert, update, delete triggerleri oluşturacaklar.

Hem bu firma özelinde hem de ilerideki bu tür ihtiyaçlarımız için, sorunu sadece yazdığımız program içinde (karşı taraftan bir talepte bulunmadan) halletmemiz yararımıza olacak.
Ömür Ölmez
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: ADO nesnesinde transaction seçimi hk.

Mesaj gönderen thelvaci »

Sql Server'ın varsayılan transaction isolation level'i Read Committed olduğu için elbette açık bir transaction varken bir başka transaction ilgili bloklara erişemez. Tabii Sql Server akıllıdır bu hususlarda, siz hangi kayıtlar ile ilgileniyorsanız sadece o kayıtları kilitler, buna da satır bazlı kilitleme denir. Ancak kilitlenecek satırların çok fazla olması durumunda Sql Server Lock escalation adı verilen bir kilit yükseltme senaryosunu devreye alır ve satır bazlı kilitten Page bazlı kilitlemeye hatta o da yeterli gelmez ise tablo bazlı kilitlemeye yükseltebilir.

Siz bazı satırları kilitli olan bir tablodan "select *" ile tüm kayıtları çekmek isterseniz eğer, kilitli satırların kilidinin açılmasını beklersiniz varsayılan izolasyon seviyesinde. Ancak kilitli olmayan satırları isterseniz herhangi bir bekleme ile karşılaşmazsınız. Yukarıda örneği paylaşılan table hint'leri de sorgularınızı kilitleme durumu ne olursa olsun kilitlenmeye maruz kalmadan almanıza yardımcı olur, ancak tabii ki bunların çok ciddi sorunlara yol açabileceğini de ifade etmeden geçemeyeceğim. Örneğin, pek sık kullanılan NOLOCK tablo hint'ini kullanarak bir sorgu aldığınızda, tablonuza yeni giren, güncellenen tüm bilgileri de görürsünüz. Bu durumda, birinci transaction yaptığı işleri commit etmemiş ise, hayalet kayıtlarınız(phantom) ve dirty read'leriniz olur. READPAST kullanırsanız da, kilitlenmiş satırların haricindeki tüm satırları herhangi bir beklemeye maruz kalmadan okuyabilirsiniz.

Ancak ben bunu da tavsiye etmiyorum elbette. Aslında kilitlenmeler ile ilgili büyük sıkıntılar yaşıyorsanız size önerebileceğim en güzel çözüm snapshot isolation. Bu izolasyon seviyesinde veritabanı üzerindeki tüm kayıtlar versiyonlama sistemine dayalı olarak tempdb üzerinde tutulurlar ve sizin sorgularınız kolay kolay locking beklemez. Tabii bu izolasyon seviyesi TempDB üzerinde ciddi bir yük oluşturacağı için; tempdb'nin cpu sayısı kadar ek file ile desteklenmesi gerekir ve bu file'ların aynı boyutlarda büyüyebilmesi için T118 flag'ını açmanız icap eder.

Sizin amacınız, canlı bir sistemdeki verilerin birebir kopyasını bir başka kaynakta almak ise eğer, tüm bu işlemlerin yerine(triggerlar vb.) Sql Server'da mevcut teknolojilerden de istifade edebilirsiniz. Log shipping, Replication, Mirroring, Always on vb. Bunları da değerlendirmeye almanız sizin için faydalı olabilir.
omurolmez
Üye
Mesajlar: 187
Kayıt: 31 Eki 2012 11:41

Re: ADO nesnesinde transaction seçimi hk.

Mesaj gönderen omurolmez »

Vakit ayırıp verdiğiniz bilgiler için çok teşekkür ederim Tuğrul Bey.

Dediğiniz gibi ikinci transaction Read Committed seçilmiş ise, ilk transaction Serializable bile olsa, ikinci transaction etkilenen kayıtar için bekletiliyor (snapshot u deneyemedim ama yazdıklarınızdan anladığım durum değişmeyecek). Sonradan farkettim ve siz de yazmışsınız ki, boş tabloda ikinci transaction ilki sonlanana kadar bekletiliyor ama neyseki veri bulunan tabloda hiç bekletilmeden varolan kayıtlar döndürülüyor.

Denemelerimden ve yazdıklarınızdan anladığım kadarıyla olmayacak birşey istemişim. Benim istediğim, öyle bir ilk transaction seçeyim ki, read committed başlayan ikinci transaction asla beklemesin ve daima ilk transaction ın başladığı andaki görüntüyü görsün. Oysa bunu yapabilmek için, asıl ikinci transaction un serializable veya snapshot seçilmesi gerekiyormuş ki ikinci transactionı başlatan başka bir firmanın kapalı kaynak yazılımı olduğu için, isteğim mümkün değil.

İlgilenen tüm arkadaşlara teşekkür ederim.
Ömür Ölmez
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: ADO nesnesinde transaction seçimi hk.

Mesaj gönderen thelvaci »

Hayır aslında tam anlatamamışım demek ki. Snapshot isolation tam da sizin istediğiniz işi yapar. Transaction'lar birbirlerini beklemezler. Bu izolasyon seviyesini test yada development ortamında denemenizi öneririm, seveceğinizi düşünüyorum. Snapshot isolation seviyesine ayarlanmış bir veritabanı üzerinde bir transaction başlatsanız ve o tamamlanmamış dahi olsa; bir başka transaction ilgili kaynakları herhangi bir sıkıntı ile karşılaşmadan kullanabilir.

Transaction türleri sanırım sizde biraz kafa karışıklığına neden olmuş. Sizin de malumunuz olduğu üzere, pek çok transaction türü var. Bunlardan kısaca bahsetmek gerekir ise; Read Uncommitted transaction pek tercih edilmeyen, edilmemesi gereken, minimum kilitlenmeye neden olan bir güvenlik mekanizmasıdır. Bu transaction sevyesinde, nerede ise hiç kilit konulmaz, dolayısı ile transaction bloğu içindeki kaynaklar başka transactionlar tarafından da rahatlıkla kullanılabilir. Ancak bir çok soruna sahiptir, dirty read, phantom records, non repeatable reads vb.

Read Committed'ı çok fazla açıklamaya gerek yok sanırım, çünkü Microsoft Sql Server'ın varsayılan transaction isolation seviyesidir. Elbette en yaygın kullanılanıdır. Transaction sevileyelerinin en katısı ise Serializable transaction isolation seviyesidir. Bu seviyede; nerede ise herkes birbirini bekler durumdadır. Kilitlenmeler, beklemeler çok fazladır ama veri bir o kadar da tutarlıdır. Transaction isolation seviyelerinden kaynaklanabilecek sorunların hiçbiri bu seviyede oluşmaz. Ama her iyi şeyin bir maliyeti olduğu gibi bu seviyenin de maliyeti, nerede ise her isteğin bir diğer isteği beklemesidir.

İşte tüm bu karmaşık ve karanlık ortamda snapshot isolation seviyesi tam da programcıların istediği gibi bir güneş gibi doğuyor transaction evrenine. Bu bağlamda bundan önce yazdığım yazıya bir daha göz gezdirmenizi rica edeceğim.

Siz bir veritabanını snapshot isolation seviyesine çekerseniz, o veritabanından sorgu alacak diğer transactionlar ister sizinle aynı veritananında olsunlar, ister aynı serverde olsunlar ister farklı serverda olsunlar farketmeyecek ve beklemeye maruz kalmayacaklardır.!

Çünkü, beklemenin nedeni consistency'dir, yani veri tutarlılığının sağlanması. Sql Server snapshot isolation seviyesinde bu işi tempdb üzerinde versiyonlama ile kendisi manage etmektedir. Kısaca, snapshot isolation seviyesindeki bir veritabanına ulaşmaya çalışan sistemlerde hangi transaction isolation seviyesinin olduğu önemli değildir, önemli olan hedefteki isolation seviyesidir. Ve siz de hedef'te snapshot isolation ayarlarsanız, bu hedeften yapacağınız sorgular nerede ise hiç beklemeye uğramayacaklardır.

Umarım şimdi biraz daha anlaşılır yazabilmişimdir.
omurolmez
Üye
Mesajlar: 187
Kayıt: 31 Eki 2012 11:41

Re: ADO nesnesinde transaction seçimi hk.

Mesaj gönderen omurolmez »

Evet hocam bu sefer gayet açık yazmışsınız, çok teşekkür ederim (Nedense, zamanında cevap yazmamışım).
Ömür Ölmez
Cevapla