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.

Güvenlik açısından en iyi isolation level Serializable’dır . Performans bakımından en hızlı çalışanı Read Uncommitted’dır.

SQL serverda isolation seviyesi ,

SET TRANSACTION ISOLATION LEVEL
(
READ COMMITTED | READ UNCOMMITTED
| REPEATABLE READ | SERIALIZABLE
)
ifadeleri ile belirtilir.

Alıntıdır.

RDBMS(Relational Database Management System) Nedir?

İlişkisel veri tabanı sisteminde veriler tablolar halinde tutulurlar ve bu tablolar kendi aralarında ilişkisel anlamda birbiri ile bağlantılı olabilirler. İlişkisel veri tabanını çeşitli tablolar arasında organize edilmiş verilerden oluşan veri tabanı olarak açıklayabiliriz. Bu farklı tablolar arasındaki veriler, çeşitli anahtarlar vasıtası ile birbirlerine bağlanırlar. İlgili tablolarda, sütunlar arasında bir anahtar sütun yer alır. Bu anahtar sütun aracılığı ile birden çok tablo verileri birbiriyle bağlantı sağlayabilir ve herhangi bir sorgulamada birlikte görüntülenebilir. Bu tür veri tabanları arasında MSSQL, PostgreSQL, MySQL, Oracle, dBase, Informix, Ingres, başta gelmektedir.

Projelerimde genelde kullandığım SQL Server, Microsoft tarafından geliştirilmiş ilişkisel veri tabanı yönetim sistemidir.
Aşağıdaki tabloda Sql Server Management Studio 2012’ye ait sürümleri ve hangilerinin hangi amaç doğrultusunda kullanıldığını görebilirsiniz.

ORM (OBJECT RELATION MAPPING) Nedir?

ORM, Object Relational Mapping anlamına gelmektedir. O/R Mapping olarakta yazılabilir.
Veritabanımızda yaratmış olduğumuz her bir nesneye karşılık kod tarafında bir nesne oluşturan programlardır diyebiliriz.Bu programlar code generation tekniği kullanarak bizim yazmamız gereken kodu otomatik üretiyor.
İlişkisel veritabanları ile Object-Oritented (Nesneye dayalı) uygulamaların arasındaki veri uyumunu sağlayan bir tekniktir. Birbirine uyuşmayan veri tipleri arasındaki veri dönüşümünü sağlar. Bu sayede biz uygulamalarımızda nesneleri kullanırken bunların veritabanında nasıl tutulduğunu dert etmeyiz. Eğer veritabanımızı iyi şekilde tasarlamışsak, nesnelerimizi de ona uygun şekilde oluşturmuşsak işimiz çok kolaylaşır. Veritabanı seviyesine inmeden uygulama verileriyle işlem yapabiliriz.

Avantajları Nelerdir?
Nesneye yönelik programlama metoduna uyumludur.
Programlama dilinden veya veritabanı çeşitlerinden bağımsız.
SQL kodu bilmeden veritabanı işlemleri gerçekleştiren uygulamalar yazabilirsiniz.
ORM araçlarının bir çoğu açık kaynak kodlu.
Polymorphism (çokbiçimlilik) gibi ilişkisel veritabanı problemlerini çözecek yapılar barındırırlar.

Dezavantajları Nelerdir?
Performans ile ilgili problemler ortaya çıkacaktır.
Veritabanı işlemlerine doğrudan etki etmeniz pek olanaklı değildir.
Hangi ORM aracını kullanacaksanız onu öğrenmek için belirli bir zaman harcamanız gerekir.

ORM araçları kullandığınız parametre ve metodlara göre sql kodlarını otomatik olarak üretir. Dolayısıyla üretilen bu kodlarda gereksiz kısımlar olabilir, efektif sql kodlarıyla işlem yapmıyor olabilirsiniz. Basit bir şey istediğinizde bu istek bir çok yapıdan geçip zaman kaybettiriyor olabilir. Bu araçlarla doğrudan sql kodu da yazabilirsiniz.

Entity Framework Power Tools for Visual Studio 2015

Öncelikle bu toolu kullanım amacımız, Mssql üzerindeki veri tabanımızı classlar halinde(poco) projemize ekleyip classlar üzerinden veri tabanına ulaşıp işlem yapmamızı sağlıyor. Bu classları tek tek manual ekleyebiliriz ama hazır tool varken kim uğraşır değil mi? 🙂
Bu toola burdan ulaşabilirsiniz.
https://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d
fakat bu tool şuan visual studio 2015 sürümüne kurulamıyor.

Ekte paylaştığım dosyayı indirip Visual Studio 2015 için kurulumu tamamlayabilirsiniz.
https://www.dropbox.com/s/pgdad5iyyclxghq/EFPowerTools.vsix?dl=0

Ekteki dosyaya yaptığım işlemide hemen açıklayayım;
1. Önce Power Tools.vsix dosyasını indirdim.

2.Vsix dosyasını winrar ile açtım ve extension.vsixmanifest dosyasını dışarı çıkattım.
3. extension.vsixmanifest dosyası içerisinde SupportedProducts tagı bulup içerisine

Enterprise

satırlarını ekledim ve winrar dosyasındaki extension.vsixmanifest dosyasını yenisiyle güncelleyip kaydettim.
4. Visual Studio 2015 Enterprise için kurulumu artık yapabilirsiniz…

Entity üzerinde sql sorgu çalıştırma

var query = “SELECT * FROM Meters WHERE CustomerId = ” + customer.sno + ” ORDER BY MeterName”;
var Meters = entity.Database.SqlQuery<Meter>(query).ToList();

 

context.Database.SqlQuery<myEntityType>(
    "mySpName @param1, @param2, @param3",
    new SqlParameter("param1", param1),
    new SqlParameter("param2", param2),
    new SqlParameter("param3", param3)
);

context.Database.SqlQuery<MyEntityType>("mySpName @param1 = {0}", param1)

return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 });

//Or

using(var context = new MyDataContext())
{
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 }).ToList();
}

//Or

using(var context = new MyDataContext())
{
object[] parameters =  { param1, param2, param3 };

return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
parameters).ToList();
}

//Or

using(var context = new MyDataContext())
{  
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
param1, param2, param3).ToList();
}

SQL Pivot Kullanımı

Pivot table bir tablodaki verileri yatay olarak göstermemizi sağlar yani satırlarda bulunan bilgileri istediğimiz alanlara göre sutunlara çevirir.  Özellikle rapor hazırlarken verileri daha anlaşılır ve düzenli hale getirmemizi sağlar. Örneğin bir sipariş tablomuz var. Bir müşterinin verdiği her bir sipariş bir satırda gösteriliyor. Her müşteri için son 2 aylık sipariş bilgilerini görmek istiyoruz. Birinci yöntem her hareketi alt alta yazmak olabilir ama daha anlaşılır ve düzenli bir rapor için her müşteri bir satırda yer almalı ve bu satırda son altı aya ait tüm sipariş tutarlarının toplamı gösterilmelidir. Bu durumda pivot table kullanmak imdadımıza yetişir.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT *
FROM (
      SELECT
       MusteriAdSoyad
      ,Donem
      ,sum(Tutar) as ToplamTutar 
      FROM Siparis
      group by MusteriAdSoyad ,Donem
     ) as gTablo
PIVOT
(
  SUM(ToplamTutar)
  FOR Donem IN ([200911],[200912],[201001])
)
AS p

Yukarıdaki sorgu sonucu aşağıdaki gibi her ay bir kolon olacak şeklide bilgilerimiz yatayda dizildi

MusteriAdSoyad 200911 200912
Ali DEMİR 80 2550
Metin TOSUN 3300 250
Sabri KUNT NULL 1580

Gördüğünüz gibi bu şeklide bir tablo oluşturmak sonucun daha düzenli olmasını sağladığı gibi incelenmesini kolaylaştırır.

SQL Tekrarlayan kayıtları bulma

SQL ile tekrarlayan(mükerrer) kayıtları ve adetlerini gösteren sorgu.

SELECT PageSlug,
COUNT(PageSlug) AS TekrarlamaSayısı
FROM News
GROUP BY PageSlug
HAVING ( COUNT(PageSlug) > 1 )

Aşağıdaki sorgu ise aynı pageslug’ı 1 defa içeren kayıtları getirecek. Yani pageslug’ı adresi yinelenmeyen kayıtların listesi dönecek.

SELECT PageSlug
FROM News
GROUP BY PageSlug
HAVING ( COUNT(PageSlug) = 1 )

Linq Rasgele kayıt getirme

Linq to sql  ile random kayıt getirmeyi isteyebiliriz. Bunu T-Sql ile

select * from tabloadi order by newID()

diyerek kayıtlarımızın random sıralanmasını sağlayabilyoruz.

Diyerek rasgele kayıtları getirmek için kullanırız.

Linq to Sql’de ise bunun için aşağıdaki komutu kullanmamız yeterlidir.

myAds = (from q in db.Ads select q).OrderBy(x => Guid.NewGuid()).Take(10).ToList();

veya

private static Random Generator = new Random();
...
var result = sc.Subjects.Where(s => s.SubName == sub && s.Level == lev).OrderBy(s => Generator.Next()).Take(10);

Order by kullanımı

Order By  Komutu
Veritabanından  çektiğimiz kayıtları (sonuç kümesini ) sıralamak için ORDER BY anahtar kelimesini kullanırız. Bu sıralama belirtilen kolona göre yapılır. Ve varsayılan olarak artan (küçükten büyüğe, ascending) sıradadır.

Bu verileri id’sine göre küçükten büyüğe(ascending) sıralamak için gerekli SQL kodu aşağıdaki gibidir.

SELECT * FROM kitapbilgisi ORDER BY id ASC

Bu verileri id’sine göre büyükten küçüğe(descending) sıralamak için SQL kodu ise aşağıdaki gibidir:

SELECT * FROM kitapbilgisi ORDER BY id DESC

Tarihe göre sıralamada bu aynı şekildedir.
Eski tarih göre sıralamak için ascending yapılır(yani 03.11.2012,04.11.2012 sırasıyla)
Yakın tarih göre sıralamak için descending yapılır(yani 04.11.2012,03.11.2012 sırasıyla)