Salı, Ocak 02, 2007

XA : Needed More Often Than You Think

Java ile uygulama geliştirenleriniz mutlaka transaction, distributed transaction, XA, XA resources, two-phase commit (2PC) terimlerini duymuştur. Bu yazıda, aslında çok ihtiyaç duyulan ama çeşitli nedenlerden kullanılmayan/kullanılamayan XA bağlantısından bahsetmeye ve ayrıca aşağıdaki sorulara da kendimce cevap bulmaya çalışacağım.

# XA bağlantısına hangi durumda ihtiyacımız var?
# XA bağlantısının uygulamaya getirdiği maliyet nedir?
# XA bağlantısı kullanmak istemiyorsak, alternatifi nedir?
# XA kullanımının sistemin genel mimarisine bir etkisi veya mimariden bir beklentisi var mıdır?


Bu sorulara cevap aramadan evvel bahsi çok geçecek bazı kavramların sözlük tanımlarına bir göz atalım.

Transaction : a series of actions performed as a single logical unit of work in which either all of the actions are performed or none of them are (also called a local or simple transaction). A transaction is often described as ACID -- atomic, consistent, isolated, and durable.

Distributed transaction : An ACID transaction between two or more independent transactional resources (for example, two separate databases). For the transaction to commit successfully, all of the individual resources must commit successfully; if any of them are unsuccessful, the transaction must roll back in all of the resources.

XA : which describes the standard protocol that allows coordination, commitment, and recovery between transaction managers and resource managers.

XA Resources : databases, messaging queuing products such as JMS, mainframe applications, ERP packages, or anything else that can be coordinated with the transaction manager.

Two-phase commit : An approach for committing a distributed transaction in two steps: Phase 1, Prepare: Each of the resources votes on whether it's ready to commit -- usually by going ahead and persisting the new data but not yet deleting the old data. Phase 2, Commit: If all of the resources are ready, they all commit -- after which the old data is deleted and the transaction can no longer roll back. Two-phase commit ensures that a distributed transaction can always be committed or always rolled back, even if parts of the system crash while the transaction is being committed. Many, but not all, distributed transaction implementations use two-phase commit.

XA bağlantısına hangi durumda ihtiyacımız var?
Eğer aynı transaction içerisinde birden fazla veritabanında güncelleme (insert/delete/update) yapıyor iseniz ve veritabanları arasında data uyumsuzluğuna (data inconsistency) tahammülünüz yok ise o zaman XA bağlantısına ihtiyacınız var demektir.

Bu durumu çok meşhur basit bir örnekle anlatmaya çalışalım. Elimizde Uygulama Sunucusunda çalışan, EJB kullanarak geliştirdiğimiz bir muhasebe programı olsun. Diyelim ki birinde stok bilgilerini, diğerinde hesapları tuttuğumuz 2 ayrı veritabanımız olsun. (Bakınız Şekil-1) Bir satış yapıldığında bir EJB metodumuz (makeSales()) da önce StockDS'i kullanarak stok'tan ilgili ürünü düşsün ve ardından AccountDS'i kullanarak toplam satış değeri kadar parayı da hesaba aktar
sın.

Figure-1. Local Connection Pools. makeSales() = t1 + t2 + t3

Bu örnekte tüm veritabanı bağlantıları hepinizin bildiği Local olarak tanımlanmış durumda. İlk bakışta herşey normalmiş gibi gözüküyor. Peki ya makeSales() metodu içerisinde gerçekleşen transaction StockDS bağlantısını commit() 'ledikten sonra tam AccountDS'e commit() komutunu gönderirken herhangi bir sorundan dolayı (network bağlantı hatası, vs.) hata alıp yarım kalırsa ne olur. Stok'umuz azalır ama hesabımıza para geçmez. Bunun sebebi de distributed transaction kullanmamız gereken bir yapıda local transaction kullanmamızdır. Yani yukarıdaki örnekteki datasource'ların kullandığı connection pool'lar local değil XA olmalıydı.


Bu tip sorunların yaşanma olasılığı düşük de olsa, günlük transaction miktarı yüksek olan sistemlerde veri tutarsızlığı (data inconsistency) çok fazla olacaktır. Hele işin için de bir de para varsa bazen 1 kuruşun bile hesabı sorulabilir.

Bazı developerlar hemen "Bizim uygulamalarımız tek bir veritabanı ile çalışıyor, bizim böyle bir sorunumuz yok" diyebilir. Eğer tek bir datasource kullanıyorsanız dediğiniz doğrudur. Lakin aynı veritabanına bakan farklı connection pool'lar tanımladıysanız ve aynı transaction içerisinde bu pool'ları kullanan datasource'lar var ise yukarıda bahsettiğimiz senaryonun aynısı gerçekleşmiş olur.

XA bağlantısının uygulamaya getirdiği maliyet nedir?

Eğer Uygulama Sunucusunda çalışan uygulamalar geliştiriyorsanız ve XA kullanmaya karar verdiyseniz tek yapmanız gereken datasource'larınızın kullandığı Connection Pool'ları Local'den XA'ye çevirmek. Fakat bu konuda hemen aksiyon almadan evvel aşağıdaki noktalara dikkat etmeniz gerekiyor.

* Öncelikle veritabanınızın XA bağlantısını destekliyor olması gerekiyor. Oracle gibi kurumsal veritabanlarının XA (distributed transaction) desteği mevcuttur. Maalesef open-source veritabanlarının çoğunda XA desteği bulunmaz.

* Uygulama Sunucunuzunda da XA transaction'ları destekliyor olması gerekiyor. Piyasadaki JBoss, Weblogic, WebSphere gibi open-source veya lisanslı bir çok uygulama sunucusunun XA desteği mevcut. Bu konuda veritabanlarına göre daha şanslıyız :)


* Teorikte birçok Uygulama Sunucusu ve Veritabanı XA desteği olduğunu söylese de, pratikte hepsinin XA desteğini başarılı bir şekilde verdiğini söyleyemeyiz. Örneğin Oracle XA konusunda senelerce çok fazla şikayet aldı. Özellikle Oracle'ın 8.x ve 9.x serisi veritabanı ve driver'ı uzun süre meşhur bug'ları ile yaşadı. (Bakınız: Oracle Thin Driver Known Issues and Workarounds) Hatta Oracle 10g çıkıncaya kadar bazı uygulama sunucuları Oracle'a bağlanmak için kendi geliştirdiği driver'larını kullandı. (Bakınız: WebLogic jDriver for Oracle (Deprecated) ) Benzer şekilde her Uygulama Sunucusunun XA desteği çok başarılı değil. Bu yüzden Uygulama Sunucusu seçiminde dikkatli olmak gerekiyor.

* XA bağlantısının performansı, doğal olarak Local bağlantıya göre biraz daha düşüktür. Bunun en büyük nedeni XA transaction'larının local transaction'lara göre sistem kaynaklarını daha fazla ve daha uzun süre meşgul etmesidir. XA bağlantısının veritabanı üzerindeki performans etkisi daha çok veritabınında kullanılan "isolation level" ve "locking" mekanizmaları ile ilgilidir. Bu konuda detaylı bilgiliyi Oracle Gurusu Hasan Tonguç Yılmaz'ın Oracle Concepts and Architecture - Part 1 blogunda bulabilirsiniz.

* XA kullanmak isteyenlerin (özellikle kurumsal şirketler) karşısına çıkan en büyük engellerden biri de Oracle store procedure ve dblink ikilisinin EJB'ler ile birlikte kullanılmasıdır. Bir XA transaction'ı içerisinde dblink kullanılıyorsa ve bu dblink'in bağlandığı veritabanı "shared" modda değilse meşhur "ORA-24777: use of non-migratable database link not allowed" hatası ile karşılaşılır. Günümüzde artık Oracle kurulumlarında daha performanslı olan "dedicated" mod kullanıldığı için bu durum XA ve dblink'in birlikte kullanımı açısından büyük bir sorun teşkil etmektedir.
XA Issues and Restrictions
Database Links : Oracle XA applications can access other Oracle Database instances through database links, with the following restrictions. Use the shared server (formerly known as Multi-Threaded Server) configuration.


Figure-2. XA Connection Pools with dblink. makeSales() = t1 + t2 + t3 + t4

Şekil-2'de bu durumu bir önceki örneğimize ilave yapıp somutlaştırmaya çalıştım. makeSales transaction'ı bu sefer hesaba para yatırdıktan sonra dblink ile Billing veritabanına bağlanıp fatura kesilebilmesi için fatura hareket tablosuna kayıt atmaya çalışıyor. Fakat Billing veritabanı "dedicated" modda olduğu için hata veriyor.

XA bağlantısı kullanmak istemiyorsak, alternatifi nedir?

XA kullanımı ile ilgili bu kadar sıkıntı gördükten sonra haklı olarak bir alternatif arayaşına gidebilirsiniz. Peki XA kullanmadan veritabanları arasındaki data uyumsuzluğunu nasıl önleyeceğiz? Bunun başlıca yöntemlerinden biri düzenli olarak manual veya otomatik veri uyumsuzluğu kontrolü (
data integrity check) yapılması. Bunun için aşağıdaki adımlar izlenebilir.

# Muhtemel data uyuşmazlığı oluşabilecek tabloların ve kayıtların önceden tespit edilmesi.
# Data uyuşmazlıklarının nasıl düzeltileceği konusunda prosedürlerinin hazırlanması
# Tespit edilen bu tablolar arasında gün içinde veya gün sonunda manual/otomatik uyumsuzluk kontrolünün yapılması
# Tespit edilen uyuşmazlıkların düzeltilmesi için gerekli manual/otomatik aksiyonların alınması.

XA kullanımının sistemin genel mimarisine bir etkisi veya mimariden bir beklentisi var mıdır?

Yukarıda da bahsettiğimiz gibi XA kullanımına geçiş kararı aslında tamamen sisteminizin mimarisini etkileyecek bir karardır. Özellikle sunum, orta ve veritabanı katmanlarının farklı farklı yazılımcılar tarafından geliştirildiği, SOA tabanlı mimarilerin kullanıldığı sistemlerde XA stratejisi çok daha kritiktir.

XA konusunda Genel Mimari'yi ilgilendirecek konuları aşağıda sıralamaya çalıştım:

# Uygulama Sunucusu tercihi
# Veritabanı tercihi
# Veritabanı Oracle ise kurulum (shared/dedicated) modu ve dblink kullanımı tercihi
# XA olmasına gerek olmayan transaction ve pool'ların tespiti. (Örneğin sadece sorgulama yapan işlemler)
# Altayapıda kullanılan framework tercihi.

XA konusunda aslında daha çok şey söylenebilir. Bu tamamen sizin sisteminizin büyüklüğüne ve karmaşıklığına bağlı. Eğer bu konuda daha detaylı ve teknik bilgiye ulaşmak isterseniz aşağıdaki linklerden faydalanabilirsiniz. Ben çok faydalandım :)

Kaynaklar
XA Transactions
Configuring and using XA distributed transactions in WebSphere Studio
Distributed Transactions and the Transaction Manager
Weblogic JDBC Datasources
Weblogic Distributed Transactions and the Two-Phase Commit Protocol
JBoss OracleXA Tricks
OReilly J2EE Transaction Frameworks

2 Yorum:

Blogger Tonguç dedi ki...

Toplantı sonrasında biraz daha tartıştık, söz uçar yazı kalır dolayısı ile buraya yorum yazmayı tercih ettim.

Ogun Heper'e katkısından oturu tesekkurler, çözümsüzlük bizim gibilere gore degil;

XA ile kullanmak için yeni db. linkler yaratırılır. Bu linkler hedef veritabanlarına SHARED modda bağlanırlar. Tabii bunun öncesinde hedef veritabanlarında SHARED modda bağlantıyı sağlayacak gerekli ayarlamalar yapılır. Bu esnada, hedef veritabanına uygulama sunucusu, vb. noktalardan gelen doğrudan bağlantılar DEDICATED veya SHARED modlardan istediklerini kullanabilirler. Uygulamaların XA kullanan bölümleri hedef veritabanlarına gitmek için yeni yaratılan SHARED mod veritabanı bağlantılarını kullanırlar.

11:52 ÖÖ  
Anonymous Onur Karadeli dedi ki...

Sevgili dostum, öncelikle sana bir merhaba diyeyim, umarım halin vaktin yerindedir.

Jboss konusu altında net farkını görmek istediğim XA ve HA (High Availability, failover oriented) DB leri farkını son derece güzel anlatmışsın. Bu yazıdan ne XA ne de "Two-Phase-commit" e ihtiyacımız olmadığı anlıyorum. HA gerekli ve yeterli.

teşekkürler
Onur Karadeli

2:41 ÖS  

Yorum Gönder

Kaydol: Kayıt Yorumları [Atom]

<< Ana Sayfa