Transaction'lar sadece menüden açılan ekranlar değil
troia-platformu-nasil-calisir yazısında transaction'ları "bağımsız bir TROIA uygulamasını tanımlayan veritabanı kaydı" olarak tanımlamıştım. Bir transaction'ı kullanıcı menüden/kısayoldan açabilir, ama kod içinden de programatik olarak çağırabilirsiniz — ve bu çağrının nasıl yapıldığı (senkron mu, sunucuda mı, arayüzsüz mü) davranışı kökten değiştiriyor.
Transaction, en büyük kapsam (scope) birimidir
Belgelerin önemli bir tanımı: transaction'lar, TROIA kodunu çalıştırabilen tek yapı. troiada-degisken-kapsamlari yazısında ele alacağım GLOBAL değişkenler, bir transaction içinde tanımlandığında o transaction kapsamındaki her dialog/class koduna açık oluyor — yani transaction, değişken kapsamının en geniş sınırını çiziyor.
Dört çağırma biçimi
1. Basit, asenkron çağrı — çağıran kod beklemeden devam eder:
CALL TRANSACTION {transactionadi} [({girdiparametreleri})];
2. Senkron çağrı, çıktı parametreli — çağıran kod, çağrılan transaction kapanana kadar durur:
CALL TRANSACTION {transactionadi} [({girdiparametreleri})] WITH WAIT [({ciktiparametreleri})];
WITH WAIT kullanıldığında, çağrılan transaction açıkken çağıran transaction'a erişilemez — kullanıcı, alt işlem bitene kadar üst ekranla etkileşemez. Bu, troiada-dialog-yasam-dongusu yazısındaki CALL DIALOG'un davranışına çok benziyor, ama burada tüm bir transaction seviyesinde.
3-5. Sunucu tarafı (arayüzsüz) çağrı — üç varyasyon, parametrelerin yerleşimine göre:
CALL TRANSACTION {transaction} ({girdiparametreleri}) INSERVER;
CALL TRANSACTION {transaction} INSERVER ({girdiparametreleri});
CALL TRANSACTION {transaction} ({girdiparametreleri}) INSERVER ({ciktiparametreleri});
INSERVER ile çağrılan bir transaction, istemci arayüzü olmadan, sunucuda tüm standart transaction işlemlerini simüle ederek çalışır — troiada-paralel-islem yazısındaki CALL TRANSACTION ... ONTHREADGROUP ... EXCLUSIVEDB örneğinde gördüğünüz kalıp da bu INSERVER ailesinin bir uzantısıydı.
Parametre geçişi ve TRANSCALLED olayı
Girdi parametreleri, çağrılan transaction içinde global değişkenlere dönüşüyor. Parametre varsa, çağrılan transaction'ın ilk dialog'unun AFTER olayından hemen sonra TRANSCALLED olayı tetikleniyor. Bu olayı implemente etmek zorunlu değil — tanımlamazsanız, parametreler global değişken olarak zaten mevcut olur ama "parametre geldi" anına özel bir tepki veremezsiniz.
Batch transaction'lar: zamanlanmış görevler
Bir transaction, işletim sistemi zamanlayıcısı (Windows Task Scheduler, Linux crontab) üzerinden batch transaction olarak da tetiklenebiliyor. Bu modda sistem, transaction'ın normal başlangıç adımlarını ve SYST00'da tanımlı "Batch Code" sekmesindeki kodu çalıştırıyor. İstemci tabanlı (görünür arayüzlü) ya da konsol tabanlı sunucu yönetim aracıyla tetiklenebilir. troiada-message-komutu yazısında bahsettiğim gibi, batch modda MESSAGE çağrıları otomatik cevaplanıyor — bu iki bilgiyi birleştirdiğinizde, bir batch transaction yazarken kullanıcı onayına dayalı hiçbir akış kurmamanız gerektiği daha da netleşiyor.
Transaction bilgisini okumak
| Değişken | Ne döner |
|---|---|
SYS_TRANSACTION |
Transaction adı |
SYS_TRANSACTIONID |
Transaction ID |
SYS_ISBATCHTRANSACTION |
Batch modda mı çalışıyor |
SYS_ISSERVERONLYTRANSACTION |
Sadece sunucu modunda mı (INSERVER) çalışıyor |
SYS_TRANCREATEDBY/SYS_TRANCREATEDAT |
Oluşturan/oluşturma tarihi |
SYS_TRANMODIFIEDBY/SYS_TRANMODIFIEDAT |
Son değiştiren/tarih |
Aynı kod parçası hem interaktif hem batch modda çalışabilecekse, SYS_ISBATCHTRANSACTION kontrolüyle davranışı dallandırmak (örneğin batch'te MESSAGE yerine bir log dosyasına yazmak) genelde daha güvenilir bir tasarım.
Gerçek bir örnek: bir onay transaction'ını sunucu tarafında tetiklemek
/* Bir sipariş onaylandığında, arayüzsüz bir muhasebe kaydı transaction'ını tetikler. */
LOCAL:
INTEGER SONUCKODU;
CALL TRANSACTION MUHKAYT01 (SIPARISNO, TUTAR) INSERVER (SONUCKODU);
IF SONUCKODU <> 0 THEN
MESSAGE 'Muhasebe kaydı oluşturulamadı, kod: ' + SONUCKODU TYPE ERROR;
ENDIF;
Sık yapılan hatalar
WITH WAIT'in çağıran ekranı tamamen bloke ettiğini unutmak — kullanıcının üst ekranla hiç etkileşemeyeceğini hesaba katmadan uzun süren bir alt transaction'ıWITH WAITile çağırmak, kullanıcı deneyimini "asılı kalmış" gibi hissettirebilir.- Batch transaction'da
TRANSCALLED'ı interaktif senaryo gibi tasarlamak — batch'te kullanıcı etkileşimi olmadığını unutup, bu olayda bir onay/mesaj akışı kurmaya çalışmak işe yaramaz. INSERVERçağrısının gerçek bir arayüz simüle ettiğini unutmak — arayüz olmasa da transaction'ın standart açılış/kapanış mantığı (dialog olayları dahil) çalışır; bu yüzdenINSERVERile çağrılan bir transaction'ın dialog kodunda görsel bir varsayım (örneğin bir kontrolün her zaman dolu olduğu varsayımı) yapmak hataya yol açabilir.SYS_ISBATCHTRANSACTIONkontrolünü atlayıp aynı kodu her ortamda aynı şekilde davranacakmış gibi yazmak — interaktif ve batch modun farklı gereksinimleri olduğunu (özellikle mesajlaşma tarafında) koda yansıtmamak, üretimde "neden kimse onaylamadan geçti" gibi sorulara yol açar.
Sıradaki adım
Bir sonraki yazıda değişken kapsamlarına (GLOBAL/MEMBER/LOCAL/OBJECT) daha derinlemesine, özellikle OBJECT anahtar kelimesinin bağlama göre nasıl farklı davrandığına değineceğim.
Yorumlar (0)
Yorum Yaz