{"id":13,"date":"2026-03-17T10:00:00","date_gmt":"2026-03-17T07:00:00","guid":{"rendered":"https:\/\/www.hasangultekin.com\/2026\/03\/17\/transactional-outbox-at-least-once-delivery\/"},"modified":"2026-03-17T10:00:00","modified_gmt":"2026-03-17T07:00:00","slug":"transactional-outbox-at-least-once-delivery","status":"publish","type":"post","link":"https:\/\/www.hasangultekin.com\/tr\/2026\/03\/17\/transactional-outbox-at-least-once-delivery\/","title":{"rendered":"\u0130\u015flemsel G\u00f6nderilecekler Kutusu, Her Bo\u015flu\u011fu De\u011fil, Sadece Bir Bo\u015flu\u011fu Kapat\u0131r"},"content":{"rendered":"<p>Bir uygulama, bir m\u00fc\u015fteri mesaj\u0131n\u0131 kaydeder ve ard\u0131ndan bir i\u015fleyici i\u00e7in bir olay yay\u0131nlar. Bu i\u015flemler aras\u0131nda uygulama \u00e7\u00f6kerse, mesaj mevcut olur ancak i\u015fleyici bundan haberdar olmaz. S\u0131ray\u0131 tersine \u00e7evirmek ise farkl\u0131 bir sorun yarat\u0131r: veritaban\u0131ndaki de\u011fi\u015fiklik hen\u00fcz ger\u00e7ekle\u015fmemi\u015fken olay mevcut olabilir.<\/p>\n<p>\u0130\u015flem g\u00f6nderim kutusu, i\u015f de\u011fi\u015fikli\u011fini ve giden olay\u0131 ayn\u0131 veritaban\u0131 i\u015fleminde depolayarak bu \u00e7ift yazma a\u00e7\u0131\u011f\u0131n\u0131 giderir. Bu, de\u011ferli bir g\u00fcvence olmakla birlikte, i\u015f ak\u0131\u015f\u0131n\u0131n tamam\u0131n\u0131n tam olarak bir kez y\u00fcr\u00fct\u00fclmesini sa\u011flamaz.<\/p>\n<h2>\u0130lk garantiyi net bir \u015fekilde belirtin<\/h2>\n<p>\u0130\u015flem onaylan\u0131rsa, hem etki alan\u0131 kayd\u0131 hem de giden kutusu kayd\u0131 mevcut olur. \u0130\u015flem geri al\u0131n\u0131rsa, ikisi de mevcut olmamal\u0131d\u0131r. Ayr\u0131 bir aktar\u0131c\u0131, giden kutusunu okur ve olaylar\u0131 arac\u0131ya iletir.<\/p>\n<p>\u015eu <a href=\"https:\/\/docs.aws.amazon.com\/prescriptive-guidance\/latest\/cloud-design-patterns\/transactional-outbox.html\" target=\"_blank\" rel=\"noopener\">AWS\u2019nin bu modele ili\u015fkin a\u00e7\u0131klamas\u0131<\/a> Bu b\u00f6l\u00fcmde, i\u015flem s\u0131n\u0131r\u0131 ve yinelenen mesajlar\u0131n i\u015flenmesi gereklili\u011fi ele al\u0131nmaktad\u0131r. Bir aktar\u0131m uygulamas\u0131n\u0131 se\u00e7meden \u00f6nce bu garantileri belirtmenin yararl\u0131 oldu\u011funu d\u00fc\u015f\u00fcn\u00fcyorum.<\/p>\n<p>Bir giden kutusu kayd\u0131, sabit bir olay kimli\u011fi, kirac\u0131 ba\u011flam\u0131, olay t\u00fcr\u00fc, \u015fema s\u00fcr\u00fcm\u00fc ve t\u00fcketiciler taraf\u0131ndan ihtiya\u00e7 duyulan etki alan\u0131 referans\u0131n\u0131 i\u00e7ermelidir. Tam bir anl\u0131k g\u00f6r\u00fcnt\u00fcn\u00fcn m\u00fc yoksa bir referans\u0131n m\u0131 eklenece\u011fi, olay\u0131n amac\u0131na ve tutarl\u0131l\u0131k gereksinimlerine ba\u011fl\u0131d\u0131r.<\/p>\n<h2>R\u00f6lede h\u00e2l\u00e2 bir ar\u0131za penceresi bulunuyor<\/h2>\n<p>Diyelim ki bir aktar\u0131c\u0131 bir olay\u0131 ba\u015far\u0131yla yay\u0131nlad\u0131ktan sonra, g\u00f6nderilecekler sat\u0131r\u0131n\u0131 \u201cg\u00f6nderildi\u201d olarak i\u015faretlemeden \u00f6nce \u00e7\u00f6kt\u00fc. Bir sonraki aktar\u0131m denemesinde bu olay yeniden yay\u0131nlanabilir. Yay\u0131nlanmadan \u00f6nce \u201cg\u00f6nderildi\u201d olarak i\u015faretlemek ise, olay\u0131n kaybolma riskini do\u011furur.<\/p>\n<p>Bu nedenle, t\u00fcketicinin yinelenen verileri alabilece\u011fini varsay\u0131yorum. Birden fazla aktar\u0131m i\u015f\u00e7isi olmas\u0131 durumunda, bir i\u015f\u00e7inin devre d\u0131\u015f\u0131 kalmas\u0131 durumunda sistemin toparlanmas\u0131n\u0131 sa\u011flarken, kontrols\u00fcz rekabeti \u00f6nleyen bir talep stratejisi de gereklidir.<\/p>\n<p>Yay\u0131nlama durumu, yap\u0131lan denemeleri, bir sonraki uygun yeniden deneme zaman\u0131n\u0131 ve son ge\u00e7erli hata mesaj\u0131n\u0131 i\u00e7ermelidir. S\u00fcrekli b\u00fcy\u00fcyen bir g\u00f6nderilecekler kutusu, sadece veritaban\u0131 eklemeleri kabul etti\u011fi i\u00e7in sa\u011fl\u0131kl\u0131 bir kuyruk de\u011fil, ara\u015ft\u0131r\u0131lmas\u0131 gereken bir birikimdir.<\/p>\n<h2>T\u00fcketicileri i\u015f s\u0131n\u0131r\u0131nda idempotent hale getirin<\/h2>\n<p>Yerel veritaban\u0131 i\u015flemleri ger\u00e7ekle\u015ftiren bir t\u00fcketici i\u00e7in, i\u015flenen olay kimli\u011fini kaydedebilir ve i\u015flemi tek bir i\u015flem i\u00e7inde uygulayabilirim. Benzersizlik k\u0131s\u0131tlamas\u0131, iki e\u015fzamanl\u0131 teslimat\u0131n ayn\u0131 i\u015flemi iki kez uygulamas\u0131n\u0131 engeller.<\/p>\n<p>D\u0131\u015f etkiler daha zordur. T\u00fcketici bir e-posta g\u00f6nderirse veya bir \u00f6deme i\u015flemi ger\u00e7ekle\u015ftirirse, veritaban\u0131ndaki bu i\u015flem uzak hizmeti i\u00e7eremez. Bu i\u015flem i\u00e7in, belirsiz sonu\u00e7lara y\u00f6nelik bir sa\u011flay\u0131c\u0131 idempotans anahtar\u0131, kal\u0131c\u0131 bir i\u015flem kayd\u0131 veya mutabakat yolu gereklidir.<\/p>\n<p>Arac\u0131 teslimat ayarlar\u0131 bu uygulama s\u0131n\u0131r\u0131n\u0131 ortadan kald\u0131rmaz. Bir JetStream al\u0131c\u0131s\u0131nda, uygulaman\u0131n i\u015fi g\u00fcvenli bir \u015fekilde tamamlanm\u0131\u015f sayabilece\u011fi durumlarda, onay ve yeniden teslimat davran\u0131\u015flar\u0131 birbiriyle uyumlu olmal\u0131d\u0131r. <a href=\"https:\/\/docs.nats.io\/learn\/jetstream\/pull-consumers\" target=\"_blank\" rel=\"noopener\">NATS kullan\u0131c\u0131 k\u0131lavuzlar\u0131<\/a> Bu, devreye al\u0131nm\u0131\u015f yap\u0131land\u0131rma i\u00e7in s\u00f6z konusu i\u015fleyi\u015fleri do\u011frulamak i\u00e7in uygun yerdir.<\/p>\n<h2>Etki alan\u0131n\u0131n hangi s\u0131ralamaya ihtiyac\u0131 oldu\u011funa karar verin<\/h2>\n<p>Genel s\u0131ralama genellikle maliyetli ve gereksizdir. Bir konu\u015fman\u0131n kendine \u00f6zg\u00fc bir s\u0131ralamas\u0131 olabilirken, bununla ilgisi olmayan konu\u015fmalar ba\u011f\u0131ms\u0131z olarak ilerleyebilir. \u0130\u015f\u00e7ilerin i\u015flerini bitirme s\u0131ras\u0131na g\u00fcvenmek yerine, bu alan gereklili\u011fini ifade etmeyi tercih ederim.<\/p>\n<p>T\u00fcketiciler, bo\u015fluklar\u0131 ve g\u00fcncel olmayan olaylar\u0131 tespit etmek i\u00e7in toplu bir s\u00fcr\u00fcm\u00fc veya diziyi kullanabilirler. Ard\u0131ndan, kurtarma politikas\u0131 beklemek, yetkili durumu yeniden y\u00fcklemek veya bir tekrar talebinde bulunmak aras\u0131nda bir karar verir.<\/p>\n<p>\u015eema s\u00fcr\u00fcmleme de \u00f6nemlidir. Bir da\u011f\u0131t\u0131m s\u0131ras\u0131nda arac\u0131da kalan bir mesaj, eski bir kod taraf\u0131ndan \u00fcretilmi\u015f olabilir. T\u00fcketicilerin, h\u00e2l\u00e2 teslim edilebilen s\u00fcr\u00fcmler i\u00e7in bir uyumluluk plan\u0131na ihtiyac\u0131 vard\u0131r.<\/p>\n<h2>T\u00fcm yolu \u00e7al\u0131\u015ft\u0131r<\/h2>\n<p>En eski yay\u0131nlanmam\u0131\u015f olay\u0131n s\u00fcresini, yay\u0131nlama hatalar\u0131n\u0131, t\u00fcketici gecikmelerini, tekrarlanan teslimatlar\u0131 ve ba\u015far\u0131s\u0131z mesaj hacmini takip ediyorum. Bu \u00f6l\u00e7\u00fcmler farkl\u0131 hata noktalar\u0131n\u0131 ortaya koyar ve tek bir kuyruk say\u0131s\u0131na indirgenmemelidir.<\/p>\n<p>Hata testlerim, yay\u0131nlamadan sonra r\u00f6leyi durdurur, yan etkisi tamamland\u0131ktan sonra t\u00fcketiciyi durdurur ve kaydedilmi\u015f bir olay\u0131 tekrar oynat\u0131r. Her test, sistemin ama\u00e7lanan i\u015flevini kaybetmeden veya etkisini katlamadan toparlan\u0131p toparlanamad\u0131\u011f\u0131n\u0131 kontrol eder.<\/p>\n<p>Giden kutusu, uygulamaya yay\u0131nlama konusunda kal\u0131c\u0131 bir taahh\u00fct sunar. Ancak t\u00fcketiciler ve sonraki a\u015famadaki entegrasyonlar, bu taahh\u00fcd\u00fc i\u015flevsel hale getirmek zorundad\u0131r.<\/p>\n<p class=\"hg-editorial-note\"><small>25 Eyl\u00fcl 2026 tarihinde g\u00fcncellenmi\u015ftir.<\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>Veritaban\u0131ndaki de\u011fi\u015fiklikleri olay yay\u0131nlamas\u0131yla ili\u015fkilendirmek i\u00e7in bir g\u00f6nderme kutusu kullan\u0131n; ard\u0131ndan yinelenen g\u00f6nderim, s\u0131ralama ve harici yan etkileri ayr\u0131 ayr\u0131 ele al\u0131n.<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"footnotes":""},"categories":[149],"tags":[163,178,194],"class_list":["post-13","post","type-post","status-publish","format-standard","hentry","category-backend-architecture","tag-distributed-systems","tag-nats","tag-transactional-outbox"],"_links":{"self":[{"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/posts\/13","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/comments?post=13"}],"version-history":[{"count":0,"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/posts\/13\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/media?parent=13"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/categories?post=13"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/tags?post=13"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}