Makale Özeti

Bu makalede ADO.NET v2.0 ile gelen yeni özellikler incelenmektedir.

Makale

ADO .NET 2.0 İle Gelen Yenilikler -1

Giriş

Microsoftun 2005 yılında, son kullanıcı ve yazılım geliştiricilerin yaşamlarını radikal bir biçimde değiştireceğinden kuşkumuz olmayan, (Longhorn, Yukon ve Whidbey isimli) teknolojilerini, özellikle son günlerde sıkça duymaktayız. Şu an beta aşamasında olan ve Visual Studio 2005 (Whidbey) ile birlikte lanse edilecek .NET Framework 2.0 da, bu yeni ürün ailesinin bir üyesi durumunda.

.NET Framework 2.0 (beta) üzerinde yapmakta olduğumuz incelemeler bize, bu yeni sürümün programcılığın diğer pek çok alanında yapacağı radikal değişikliklerin, veri tabanı programcılığı alanında da kaçınılmaz olacağı izlenimini uyandırıyor. .NET vizyonunun veri tabanı erişim teknolojisi konumundaki ADO .NET, içerisinde yer aldığı Frameworkün izlediği evrim çizgisinin paralelinde, özellikle SQL Server 2005 (Yukon) üzerine odaklı bir takım marjinal değişiklik ve eklentileri barındırmaktadır. Sözgelimi : 

  • MARS (Multiple Active ResultSets),
  • Dataset - DataReader entegrasyonu,
  • Dataset üzerinde gerçek anlamda binary serialization yapma imkanı,
  • Asenkron veri tabanı işlemleri,
  • Batch update,
  • Bulk copy,
  • Provider bağımsız kodlama imkanı sağlayan DBProviderFactory sınıfı,
  • Data paging (veri sayfalama),
  • Tracing,
  • İstatiksel bilgi edinme,
  • Connection String Builder,
  • Sunucu sayımlama, 
  • Bağlantı havuzlama (Connection pooling) konusundaki eklentiler, ...

MARS (Multiple Active ResultSets)

Kısaca MARS ismi ile anılan bu özellik, SQL Server 2005 (Yukon) üzerinde açılmış tek bir bağlantı üzerinde birden fazla DataReader nesnesi ile veri erişimine olanak sağlar.

Oysa hatırlanacağı gibi ADO .NET in önceki versiyonlarında var olan XxxDataReader isimli sınıflar, bir bağlantı üzerinde çalışan DataReader nesnesini kapatma amacı ile kullanılan Close() isimli metodu içermekteydi. Bu metodun tipik kullanım nedeni; hem DataReader nesnesini kapatmak hem de  DataReader nesnesinin üzerinde çalışmış olduğu bağlantının başka amaçlar için de kullanılabilmesini sağlamaktır. Zira açılan bir DataReader nesnesi, kendisi ile ilişkilendirilen bağlantıyı, Close() metodu çağrılana kadar, meşgul edecek şekilde çalışır. Başka bir deyişle, açılan bir DataReader kapatılana kadar, aynı bağlantı üzerinde başka bir DataReader açılamaz. Örneğin aşağıdaki kod parçası, There is already an open DataReader associated with this connection which must be closed first hatasının alınmasına neden olmaktadır.

[ADO.NET 1.X]

SqlConnection cnn = new SqlConnection ("data source= localhost;
initial catalog=northwind; integrated security=true");
cnn.Open();

SqlCommand cmd = new SqlCommand("Select * from Employees", cnn);

SqlDataReader dr1 = cmd.ExecuteReader();

There is already an open DataReader associated with this connection which must be closed first
SqlDataReader dr2 = cmd.ExecuteReader();

İpucu : Default olarak açık durumda olan bu özellik, gerekirse connection string içerisine eklenen "MultipleActiveResultSets= False" ifadesi ile devre dışı da bırakılabilmektedir.

Bu özelliğin marjinal faydası; özellikle asenkron veri alma işlemlerini optimize ediyor olmasıdır. Sözgelimi aynı pencere üzerindeki beş farklı combo kontrolünün, "aynı anda" veri tabanından alınan bilgilerle doldurulması gerekiyor ise, MARS özelliği sayesinde beş farklı bağlantı açılmaksızın amaca ulaşmak mümkün olacaktır. Bu durum özellikle aktif bağlantıların tükettiği sistem kaynaklarının büyüklüğü göz önüne alınırsa, MARS kullanımından sağlanacak getirinin ne denli önemli olduğu daha net anlaşılabilir.

Uyarı : MARS özelliği sadece SQL Server 2005 (Yukon) ile kullanılabilmektedir !

Connection Pooling Konusundaki Eklentiler

ADO.NET 1.0 da, SqlClient ve OracleClient managed providerları için veri tabanı bağlantılarının havuzlanmasını sağlayan bir altyapı öngörülmüştü. Bu altyapı sayesinde, -aynı connection string bilgisi üzerine yapılandırılmış olan- bağlantı nesneleri havuzlanarak, nesne yaratma ve yok etme zamanından tasarruf etmek mümkün olabilmekteydi.

ADO.NET 2.0 da ise, var olan bu altyapı üzerine bir takım eklenti ve geliştirmeler yapılmıştır. Sözgelimi havuz boyutlarının belirlenmesi veya nesnelerin ne kadarlık bir süre için havuzlanacağı gibi argümanlar, programcının insiyatifi doğrultusunda değiştirilebilir hale gelmiştir. Keza belirli bir havuzun programatik olarak yok edilişi ya da tüm havuzların yok edilişini sağlayan ClearPool(s) isimli statik metotlar, SqlClient ve OracleClient providerlarına eklenmiştir.

Tracing

Pratikteki deneyimler, veritabanı erişimi noktasında yaşanan olumsuzlukların ve bunlara bağlı alınan hataların takip ve anlamlandırılmasının zor olduğunu kanıtlar niteliktedir. Genel olarak, bu çerçevede karşılaşılan sorunları aşağıdaki gibi özetlemek mümkündür :

  • Veritabanı ve uygulama arasındaki şema uyuşmazlıkları,
  • Veritabanı ya da network kaynaklı sorunlar,
  • Yanlış yazılmış veya oluşturulmuş SQL deyimleri,
  • Hatalı kodlar ya da hatalı tasarlanmış uygulamalar.

Geçmişte bu tür sorunların neden olduğu hataların takibi, sadece kullanılan data providerın sunduğu özelliklerle sınırlı kalmaktaydı. Oysa ADO.NET 2.0daki providerlar, standardize edilmiş bir tracing kabiliyetine sahiptir. Böylece programcılar veritabanı erişimine ilişkin, herhangi bir seviyedeki sorunu bu yeni özelliği kullanarak tanımlayabilmekte ve çözebilmektedirler.

İstatiksel Bilgi Edinme

Uygulamalarının çalışma sürecindeki performans eğilimleri gözlemleyebilmek, pek çok programcı için vazgeçilmez bir özellik durumundadır. Bu amaca hizmeten kullanılan performance counter bileşenleri ve gözlem araçları sayesinde, yazılan uygulamaları farklı performans kriterlerine göre ölçümleyebilmekteyiz.  

ADO.NET 2.0 / SQLClient managed providerı veritabanı işlemlerine ilişkin ve bağlantı bazlı bir takım istatistiksel bilgileri, tasarımcıya sunabilecek yeni programatik araçları barındırmaktadır. Örneğin :

SqlConnection.StatisticsEnabled : Default değeri false olan bu propertye true değeri atanarak, bağlantı bazlı istatistiksel veri alımı yapılır.

SqlConnection.RetrieveStatistics() : Bu metodun  döndürdüğü IDictionary referansı ile söz konusu veriler anahtar-değer çiftleri biçiminde elde edilmektedir.

SqlConnection.ResetStatistics() : Bu metot sayaçları ilk hallerine döndürme amacına yönelik tasarlanmıştır.

Örnek :

SqlConnection conn = new SqlConnection("data source=localhost; initial catalog=northwind; integrated security=true");
conn.Open(); 

conn.StatisticsEnabled = true;

// çeşitli işlemler
SqlCommand cmd = new SqlCommand("select * from employees", conn);
SqlDataReader rdr = cmd.ExecuteReader();

// İstatistiksel bilgilerin alınışı ve işlenmesi
Hashtable stats = (Hashtable)conn.RetrieveStatistics();
IDictionaryEnumerator e = stats.GetEnumerator();
while (e.MoveNext())
    Console.WriteLine("{0} : {1}", e.Key, e.Value);

conn.ResetStatistics();
Console.ReadLine();

Çıktı :

//NetworkServerTime : 10
//BytesReceived : 8000
//UnpreparedExecs : 1
//SumResultSets : 0
//SelectCount : 0
//PreparedExecs : 0
//ConnectionTime : 20
//ExecutionTime : 20
//Prepares : 0
//BuffersSent : 1
//SelectRows : 0
//ServerRoundtrips : 1
//CursorOpens : 0
//Transactions : 0
//BytesSent : 54
//BuffersReceived : 1
//IduRows : 0
//IduCount : 0


Kaynaklar :

  • .NET Framework 2.0 SDK
  • MSDN-ADO_NET 2_0 Feature Matrix
  • VB .NET İle Veri Tabanı Programlama & ADO.NET
    (Aykut TAŞDELEN)

Aykut TAŞDELEN
MVP (MS Most Valuable Professional)