5 Ağustos 2010 Perşembe

JPA'da @version tagı kullanılarak optimistic locking mekanizmasının sağlanması

JPA'da @version tagı veritabanına birden çok kişinin aynı anda erişmesi durumunda  optimistic locking mekanizmasının kullanılmasını sağlar. Bir tabloda sadece bir tane version alanı olabilir. Normal şartlarda veritabanlarında optimistic veya pessimistic locking kullanılmadığında  birden çok kişi aynı anda veritabanina eriştiğinde birbirini ezme prensibi kullanılıyor yani en son yapılan değişiklik daha önceki değişiklikleri eziyor. Arkadaşımla yaptığımız denemelerde aynı anda  veritabanina eriştikten sonra önce ben değişiklik yapıp commitledim daha sonra arkadaşım değişiklik yapıp commitledi ve onun yaptığı değişiklik benim yaptığım değişikliği ezdi. Version alanı kullanarak yaptığımız denemelerde ise ben veritabanina eriştim ve bazı değişiklikler yaptım ve commitlemedim, daha sonra arkadaşım tabloya erişerek bazı değişiklikler yapmaya çalıştı ama sistem buna ben commit yapmadan izin vermedi.Sistem sadece veritabaninin o anki durumunu görmesine izin verdi.
Version alanının kullanılma mantığı şu şekildedir, kullanıcı veritabanında bir alana eriştiğinde version alanındaki değer kontrol ediliyor sistem tarafından ve kullanıcı herhangi bir değişikli yaptığı anda version alanındaki değer bir kez daha kontrol ediliyor ve eğer bu değer sisteme ilk girildiğinde kontrol edilen değere eşitse (bu değer veritabanında herhangi bir değişiklik yapıldığı zaman değişiyor.) o zaman kullanıcının değişiklik yapmasına izin veriliyor. Version alanındaki değer her değişiklik sonrası bir arttırılıyor.Eğer alana eriştiğimiz andaki version değeriyle değişiklik yaptığımız andaki version değeri farklıysa bu başka birinin bizim sisteme giriş yaptığımız ve değişiklik yaptığımız zaman arasında o alanda başka bir değişiklik yaptığını gösterir ve değişikli yapmamıza izin vermez.Version alanı timestamp( en son değişiklik yapılma tarihi ) veya numeric türde değişken kullanılabilir ama Oracle numeric değişkenlerin kullanılmasını öneriyor.çünkü time stamp değişkenler veritabanında %100 kesin değerleriyle tutulamaz ve neredeyse nano saniye farkla yapılan farklı commitler arasındaki farkı algılayamayabilir.

Not: Arkadaşım Anıl Mercana yardımlarından dolayı teşekkür ediyorum.

2 Ağustos 2010 Pazartesi

Interface ve Abstract

Head First Java (Second Edition) kitabında gerçekten çok güzel örnek verilmiş interface ve abstract arasındaki farkı anlamak için. Elimizde kedi,  köpek, aslan,  kaplan, suaygırı, kurt gibi hayvanlar var ve bunları belli bir hiyerarşiye göre dizmemiz gerekiyor daha sonra polimorfizm gibi yöntemlerden rahatça faydalanabilmemiz için. Öncelikle bütün bu elimizdeki canlıların hayvan olduğu bilindiğinden ve hepsinin yemek, uyumak, acıkmak gibi hayvanlara özgü ortak özellikleri bulunduğundan öncelikle Hayvan adında abstract bir sınıf oluşturuyoruz. Daha sonra kedi, kaplan ve aslan gibi hayvanlarda ortak özelliklere sahip olduklarından dolayı Kedigiller adında abstract bir sınıf oluşturuyoruz ve kedi, kaplan ve aslanı bu abstract sınıftan extend ediyoruz. Aynı şekilde köpek ve kurt da birçok ortak özelliğe sahip olduğundan bu hayvanların ortak özelliklerini barındıran canine(köpek ve benzeri hayvanlar) adında abstract bir sınıf oluşturuyoruz. Kurt ve köpeği canine sınıfından extend ettikden sonra suaygırını da direk hayvan adlı abstract sınıftan extend ediyoruz.

Daha sonra şöyle bir sorunla bizden evcil hayvanlara ait olan ‘oyna’ ve ‘sevimli ol’ gibi metodların kedi ve köpek gibi evcil hayvanlara dahil etmemiz isteniyor. Bunu yapmanın birçok yolu geliyor hemen aklımıza ilki hayvan adlı abstract sınıfın içerisine bunları abstract metodlar olarak dahil ederek tüm aly sınıflarda bu özelliklerin sağlanmasını garantiye almak. Ancak bu çözüm yolu nesne yönelimli programlamanın birçok prensibini altüst ediyor çünkü bu durumda aslan ve kaplan gibi hayvanlara da gövdesini doldurmasak bile sevimliol() oyna() gibi metodlara sahip olma imkanı sağlıyor. Bu durumda bu yöntemin sorunumuzu çözmediğini görüyoruz ve başka bir çözüm yolu aramaya devam ediyoruz.Bir başka çözüm yolu da kedi ve köpek gibi evcil hayvanlara ait olan sınıfların içine ayrı ayrı evcil hayvanlara ait metodları yazmak olabilir. Ancak bu durumda da polimorfizm gibi bir özelliği kullanmaktan mahrum oluyoruz. Ayrıca aynı işlevi yapmak için yazılmış metodlar farklı isimlerde olabilir örneğin kedi için sevimliOl() adını verdiğimiz metodun karşılığı köpek içerisinde tatlıOl() şeklinde olabilir bu da çeşitli karışıklıklara neden olur.

Bu sorunu çözecek en iyi çözem yolu çoklu kalıtımdır! Ancak Java çoklu kalıtım çok fazla karışıklık yarattığından dolayı desteklemez. Peki bu durumda ne yapmamız gerekiyor?
İşte bu durumda imdadımıza Interface yetişiyor çünkü javada bir sınıfı birden çok abstract sınıftan extend edemeyiz ancak birçok interfaceden implemente edebiliriz. Ayrıca bir sınıfı bir abstract sınıftan ve bir veya birden çok interfaceden implemente etme şansımız da vardır.
Sorunumuza dönersek, Pet adında bir interface yazarız ve bu interface’in içerisinde sevimliOl() oyna() gibi gövdesi boş metodlar tanımlarız(interfacelerde içi dolu metodlar tanımlayamıyoruz sadece içi boş metodlar tanımlayabiliriz. İşte bu yüzden java abstract sınıflarla çoklu kalıtım yapmamıza izin vermediği halde interfacelerle çoklu kalıtım yapmamıza imkan sağlıyor. ). Daha sonra kedi ve köpek gibi evcil hayvanları hayvan sınıfından extend ve pet interface’den implement ederiz. Böylece nesne yönelimli programlamanın polimorfizm gibi çok değerli özelliklerinden faydalanabileceğiz.