[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f2ihp2ibctvwtv":3,"$f3eeskxabac9ua":178},{"data":4},[5],{"id":6,"slug":7,"locale":8,"type":9,"title":10,"subtitle":11,"summary":12,"body":13,"primary_topic":14,"knowledge_status":15,"practical_validation":16,"workflow_status":17,"author_id":18,"published_at":19,"updated_at":19,"review_due_at":20,"canonical_url":21,"seo_title":10,"seo_description":12,"hero_asset_id":20,"reading_time":22,"version":23,"technology_versions":24,"review_frequency_days":25,"parent_content_id":26,"sort_in_parent":27,"hub_entry_status":28,"content_blocks":29,"hero_alt_text":21,"hero_caption":21,"hero_credit":21,"publication_scope":168,"access_level":169,"approved_at":170,"approved_by":171,"review_note":21,"home_enabled":172,"home_slot":173,"home_variant":174,"home_priority":175,"home_eyebrow":20,"home_valid_from":20,"home_valid_to":20,"home_image_asset_id":20,"promotion_kind":176,"sponsor_name":20,"sponsor_url":20,"sponsor_disclosure":177},"2fb56178-4357-4937-997a-3a3a71cf88c5","modernizzazione-legacy-sanitario-transactional-outbox-idempotenza","it","CAPSULE","Transactional Outbox, Inbox e Idempotenza: eventi affidabili","Evitare il buco tra commit del database e pubblicazione del messaggio, gestendo correttamente le rideliveries.","Outbox, Inbox e Idempotenza rendono affidabili i flussi event-driven senza richiedere transazioni distribuite tra database e broker.","Il problema del dual write\nSupponiamo che ADT salvi un ricovero e poi pubblichi PatientAdmitted. Se il database fa commit ma il processo muore prima del publish, il ricovero esiste ma nessun consumer riceve l'evento. Se si pubblica prima e poi fallisce il commit, i consumer reagiscono a un fatto che non esiste. Due sistemi separati non condividono automaticamente la stessa transazione.\nTransactional Outbox\nLa soluzione è scrivere nella stessa transazione locale sia la modifica di dominio sia un record outbox. Dopo il commit, un publisher indipendente legge l'outbox e invia il messaggio al broker. Solo dopo conferma marca l'evento come pubblicato o avanza il proprio offset.\nSequenza\nBEGIN transaction.\n\nAggiorna l'aggregate, per esempio Encounter.\n\nInserisce OutboxEvent con eventId, type, aggregateId, payload e timestamp.\n\nCOMMIT: dominio ed evento diventano persistenti insieme.\n\nOutbox publisher invia l'evento a RabbitMQ.\n\nIl messaggio può essere ritentato finché non viene confermato.\n\nPerché serve l'idempotenza\nLa consegna affidabile è normalmente at-least-once: lo stesso evento può arrivare più di una volta. Il consumer non deve quindi assumere unicità della consegna. Deve rendere idempotente l'effetto o memorizzare gli eventId già processati.\nInbox Pattern\nUn consumer può registrare in una tabella inbox l'identificatore del messaggio dentro la stessa transazione con cui applica la modifica locale. Se riceve di nuovo lo stesso eventId, riconosce la ridelivery e non ripete l'effetto.\nIdempotency Key per API\nLo stesso principio vale per comandi HTTP a rischio di retry, per esempio creazione ordine o richiesta documento. Il client invia una idempotency key; il server restituisce lo stesso risultato a richieste duplicate invece di creare due risorse.\nCose da non confondere\nOutbox garantisce che l'intenzione di pubblicare sia persistita con la transazione di dominio.\n\nInbox\u002Fdedup protegge il consumer dalle rideliveries.\n\nRetry decide quando riprovare; non sostituisce l'idempotenza.\n\nExactly-once end-to-end è spesso un'illusione costosa: progettare effetti idempotenti è più robusto.\n\nIn un'architettura sanitaria event-driven, Outbox + idempotenza dovrebbe essere considerato un requisito di affidabilità, non un miglioramento opzionale.","58ba728e-da9d-409d-a6c7-31325e3773a8","REVIEWED","NOT_PERFORMED","PUBLISHED","fbbfd4b6-f4c7-4740-94a6-f81eb8fbb1b2","2026-08-25T18:17:54.623Z",null,"",9,3,{},365,"776fc737-dda9-4c82-bd56-b6ba0b7148d6",13,"AVAILABLE",[30,164],{"id":31,"type":32,"version":33,"doc":34},"ce0423d3-06d8-509e-b2f6-55aea1a158cc","rich_text",1,{"type":35,"content":36},"doc",[37,45,50,55,59,64,105,110,114,119,123,128,132,137],{"type":38,"attrs":39,"content":41},"heading",{"level":40},2,[42],{"type":43,"text":44},"text","Il problema del dual write",{"type":46,"content":47},"paragraph",[48],{"type":43,"text":49},"Supponiamo che ADT salvi un ricovero e poi pubblichi PatientAdmitted. Se il database fa commit ma il processo muore prima del publish, il ricovero esiste ma nessun consumer riceve l'evento. Se si pubblica prima e poi fallisce il commit, i consumer reagiscono a un fatto che non esiste. Due sistemi separati non condividono automaticamente la stessa transazione.",{"type":38,"attrs":51,"content":52},{"level":40},[53],{"type":43,"text":54},"Transactional Outbox",{"type":46,"content":56},[57],{"type":43,"text":58},"La soluzione è scrivere nella stessa transazione locale sia la modifica di dominio sia un record outbox. Dopo il commit, un publisher indipendente legge l'outbox e invia il messaggio al broker. Solo dopo conferma marca l'evento come pubblicato o avanza il proprio offset.",{"type":38,"attrs":60,"content":61},{"level":40},[62],{"type":43,"text":63},"Sequenza",{"type":65,"attrs":66,"content":67},"orderedList",{"start":33,"type":20},[68,75,81,87,93,99],{"type":69,"content":70},"listItem",[71],{"type":46,"content":72},[73],{"type":43,"text":74},"BEGIN transaction.",{"type":69,"content":76},[77],{"type":46,"content":78},[79],{"type":43,"text":80},"Aggiorna l'aggregate, per esempio Encounter.",{"type":69,"content":82},[83],{"type":46,"content":84},[85],{"type":43,"text":86},"Inserisce OutboxEvent con eventId, type, aggregateId, payload e timestamp.",{"type":69,"content":88},[89],{"type":46,"content":90},[91],{"type":43,"text":92},"COMMIT: dominio ed evento diventano persistenti insieme.",{"type":69,"content":94},[95],{"type":46,"content":96},[97],{"type":43,"text":98},"Outbox publisher invia l'evento a RabbitMQ.",{"type":69,"content":100},[101],{"type":46,"content":102},[103],{"type":43,"text":104},"Il messaggio può essere ritentato finché non viene confermato.",{"type":38,"attrs":106,"content":107},{"level":40},[108],{"type":43,"text":109},"Perché serve l'idempotenza",{"type":46,"content":111},[112],{"type":43,"text":113},"La consegna affidabile è normalmente at-least-once: lo stesso evento può arrivare più di una volta. Il consumer non deve quindi assumere unicità della consegna. Deve rendere idempotente l'effetto o memorizzare gli eventId già processati.",{"type":38,"attrs":115,"content":116},{"level":40},[117],{"type":43,"text":118},"Inbox Pattern",{"type":46,"content":120},[121],{"type":43,"text":122},"Un consumer può registrare in una tabella inbox l'identificatore del messaggio dentro la stessa transazione con cui applica la modifica locale. Se riceve di nuovo lo stesso eventId, riconosce la ridelivery e non ripete l'effetto.",{"type":38,"attrs":124,"content":125},{"level":40},[126],{"type":43,"text":127},"Idempotency Key per API",{"type":46,"content":129},[130],{"type":43,"text":131},"Lo stesso principio vale per comandi HTTP a rischio di retry, per esempio creazione ordine o richiesta documento. Il client invia una idempotency key; il server restituisce lo stesso risultato a richieste duplicate invece di creare due risorse.",{"type":38,"attrs":133,"content":134},{"level":40},[135],{"type":43,"text":136},"Cose da non confondere",{"type":138,"content":139},"bulletList",[140,146,152,158],{"type":69,"content":141},[142],{"type":46,"content":143},[144],{"type":43,"text":145},"Outbox garantisce che l'intenzione di pubblicare sia persistita con la transazione di dominio.",{"type":69,"content":147},[148],{"type":46,"content":149},[150],{"type":43,"text":151},"Inbox\u002Fdedup protegge il consumer dalle rideliveries.",{"type":69,"content":153},[154],{"type":46,"content":155},[156],{"type":43,"text":157},"Retry decide quando riprovare; non sostituisce l'idempotenza.",{"type":69,"content":159},[160],{"type":46,"content":161},[162],{"type":43,"text":163},"Exactly-once end-to-end è spesso un'illusione costosa: progettare effetti idempotenti è più robusto.",{"id":165,"type":166,"version":33,"text":167},"de9dedc1-24a8-5ce2-bcf2-776b20cac78b","callout","In un'architettura sanitaria event-driven, Outbox + idempotenza dovrebbe essere considerato un requisito di affidabilità, non un miglioramento opzionale.","PORTAL","ANONYMOUS","2026-08-25T18:17:53.323Z","794a9185-136c-4415-ab23-cd144eb5870e",false,"LATEST","AUTO",0,"EDITORIAL","Sponsorizzato",{"sources":179,"secondaryTopics":180,"tags":181,"primaryTopic":182,"technologies":186},[],[],[],[183],{"id":14,"name":184,"slug":185},"Software Architecture","software-architecture",[]]