Makale Özeti

Veri tabanları üzerinde yapageldiğimiz transaction tabanlı işlemleri, farklı bir metodoloji kullanarak, mesaj kuyrukları üzerinde de gerçekleştirmek mümkündür. Mesaj kuyrukları üzerinde gerçekleştirilen transaction tabanlı işlemler için, kullanılan yöntemler her ne kadar farklı olsa da, önceki bölümde anlatılan ilkeler aynen geçerlidir.

Makale

Veri tabanları üzerinde yapageldiğimiz transaction tabanlı işlemleri, farklı bir metodoloji kullanarak, mesaj kuyrukları üzerinde de gerçekleştirmek mümkündür. Mesaj kuyrukları üzerinde gerçekleştirilen transaction tabanlı işlemler için, kullanılan yöntemler her ne kadar farklı olsa da, önceki bölümde anlatılan ilkeler aynen geçerlidir.

Mesaj kuyrukları üzerinde gerçekleştirilen transaction tabanlı işlemler; içsel ve dışsal transaction’lar biçiminde kategorize edilmiştir. İçsel transaction’ların yönetimi, MessageQueueTransaction sınıfına ait üyeler kullanılarak ve manuel biçimde yapılır. Mesaj kuyrukları üzerindeki içsel transaction işlemlerini; ADO .NET kütüphanesindeki XxxTransaction sınıflarını kullanarak yapılan işlemlere benzetmek mümkündür.

İçsel transaction‘ların çalışmaları; Message Queuing Transaction Coordinator tarafından kontrol edilir. Dışsal transaction’lar ise; MS DTC (Microsoft Distributed Transaction Coordinator) tarafından kontrol edilir. Kontrol ve yönetim farklılıklarının yanı sıra, hız ve performans açısından bir karşılaştırma yapmak gerekirse, içsel transaction’ların kullanımı tavsiye edilmektedir.

Bir Mesaj Kuyruğuna Transaction Desteği Sağlanması

Bu amaçla MessageQueue sınıfına ait Create() fonksiyonu, ikinci parametresine true değeri geçirilerek çağırılmalıdır. Örneğin;

MessageQueue.Create(".\Private$\Queue",True)

İçsel bir transaction’ının başlatılması ise, MessageQueueTransaction sınıfına ait Begin() isimli metot kullanılarak yapılan bir işlemdir.

Dim oTrs As MessageQueueTransaction
oTrs = New MessageQueueTransaction()
oTrs.Begin()

İşlemlerin Transaction Çerçevesine Alınması

Mesaj kuyruğu üzerinde yapılacak mesaj gönderme ya da mesaj alma gibi işlemlerin ACID doktrinine uygun olabilmesi için, bir transaction çerçevesinde gerçekleştirilmeleri gerekir. Begin() metodu kullanılarak, başlatılmış olan bir transaction ile, transaction çerçevesinde yapılmak istenen işlemlerin birbirleri ile ilişkilendirilmesi Send(), Receive() ya da Peek() gibi metotların transaction desteği ile çalışabilen versiyonlarının kullanımı ile sağlanır. Örneğin transaction çerçevesinde mesaj gönderme işlemi;

oQue.Send(“Mesaj içeriği”, oTrs)

İçsel Transaction’ların Sonlandırılması

Begin() metodu ile çalışması başlatılmış bir tranasaction’ının ACID ilkeleri gereğince sonlandırılabilmesi için, MessageQueueTransaction sınıfına iki metot eklenmiştir. Transaction‘ına ait tüm alt işlemlerin başarı ile tamamlandığını (ya da atomicity ilkesinin gerçekleştiğini düşünen) ve yapılan işlemlerin kalıcı hale gelmesini isteyen programcı, bu isteğini MessageQueueTransaction sınıfının Commit() isimli fonksiyonunu çağırarak gerçekleştirir. Transaction‘ına ait alt işlemlerin herhangi birisinin başarısızlıkla sonuçlandığını (ya da atomicity ilkesinin gerçekleşmediğini düşünen) ve yapılan tüm işlemlerin geri alınmasını isteyen programcı, bu isteğini MessageQueueTransaction sınıfının Abort() isimli fonksiyonunu çağırarak gerçekleştirir.

Örnek : Aşağıdaki uygulamada öncelikle Queue isimli mesaj kuyruğu üzerinde manuel bir transaction başlatılmıştır. Bu transaction çerçevesinde iki mesaj kuyruğa gönderilmiş ve bu işlemlerin kalıcı hale gelmesi için Commit() metodu çağrılmıştır. Daha sonra bu iki mesaj Receive() metodu ile kuyruktan silinerek alınmıştır. Yorum karakterleri ile kapatılan satırlar açılarak, uygulama tekrar çalıştırılırsa; bu iki satırda gerçekleşen mesaj okuma işleminin, Commit() metodu çağrılmadan önce yapılması dolayısı ile bir hata oluşacaktır. Hatanın nedeni; Commit() metodunun bu aşamada henüz çağrılmamış olması, dolayısı ile mesajların henüz kuyruğa eklenmemiş olmalarıdır. Üç saniyelik time-out süresinin aşılmasının ardından, akış catch kısmına atlayarak devam eder ve yapılan işlemler geri alınarak, kullanıcıya bir hata mesajı verilir.

Dim oQue As MessageQueue
oQue = New MessageQueue(".\Private$\Queue")
oQue.Formatter = New XmlMessageFormatter( _
New Type() {GetType(String)})
Dim Msg As System.Messaging.Message
Msg = New System.Messaging.Message()
Dim oTrs As MessageQueueTransaction
oTrs = New MessageQueueTransaction()
oTrs.Begin()
Try
    Msg.Body = "Mesaj 1"
    oQue.Send(Msg, oTrs)
    Msg.Body = "Mesaj 2"
    oQue.Send(Msg, oTrs)
    ‘Msg = oQue.Receive(New TimeSpan(0,0,3), oTrs)
    ‘MessageBox.Show(Msg.Body.ToString())
    ‘İşlemlerin kalıcı hale getirilmesi
    oTrs.Commit()
    Msg = oQue.Receive(oTrs)
    MessageBox.Show(Msg.Body.ToString())
    Msg = oQue.Receive(oTrs) 
    MessageBox.Show(Msg.Body.ToString())
Catch
    oTrs.Abort()
    MessageBox.Show("Yapılan işlemlerde hata oluştu")
End Try


Aykut TAŞDELEN

aykuttasdelen@yazgelistir.com