Masalah dan Kes Penggunaan
Penerima menukar permintaan HTTP yang tidak dipercayai kepada peristiwa dalaman yang tahan lama. Bahagian yang sukar ialah sempadan antara keadaan-keadaan tersebut. 200 OK yang pantas adalah salah jika proses boleh terhenti (crash) sebelum menyimpan peristiwa tersebut. Menjalankan aliran kerja pembayaran sebelum bertindak balas juga salah kerana kebergantungan yang perlahan menyebabkan percubaan semula oleh penyedia dan meningkatkan beban.
Gunakan andaian temu duga ini:
- Trafik puncak ialah 2,000 permintaan sesaat. Purata badan mentah ialah 10 KiB dan maksimum ialah 1 MiB, jadi ingress badan purata pada waktu puncak adalah kira-kira 19.5 MiB/s sebelum overhed pengepala, replikasi, dan storan.
- Penyedia menjangkakan respons dalam masa 2 saat. Sasaran dalaman kita ialah perakuan p99 selama 500 ms untuk mengekalkan ruang simpanan (headroom).
- Penghantaran adalah sekurang-kurangnya sekali (at least once) dan tidak berurutan. Penyedia mungkin menghantar peristiwa logik yang sama secara serentak, mencubanya semula kemudian, atau menghantar keadaan objek yang lebih baharu terlebih dahulu.
- Peristiwa yang diterima mesti kekal bertahan walaupun penerima mengalami ranap sistem dan akhirnya mencapai keadaan terminal
PROCESSEDatauFAILED. Satu peristiwa logik tidak boleh menggunakan mutasi perniagaan yang sama sebanyak dua kali. - Rahsia menandatangani bertukar ganti (rotate) tanpa masa henti (downtime). Muatan mentah disulitkan dan disimpan selama 30 hari untuk pemulihan dan audit; rekod keidempotentan kekal sekurang-kurangnya sepanjang tetingkap penghantaran semula yang didokumentasikan oleh penyedia.
Kes penggunaan utama ialah kemas kini keadaan pembayaran, perubahan kitaran hayat langganan, bayaran balik, pertikaian, dan pemberitahuan akaun. Reka bentuk mesti berfungsi merentas pelbagai penyedia tanpa menganggap pengepala, algoritma tandatangan, identiti percubaan semula, atau peraturan cap masa mereka adalah serupa.
Perkara yang Dinilai oleh Penemu Duga
Pertama, penemu duga mahukan kontrak perakuan yang tepat. 2xx bermaksud "penerima ini telah menerima peristiwa secara tahan lama," bukan "setiap kesan sampingan hiliran telah selesai." Mengembalikan kejayaan sebelum penulisan tahan lama mewujudkan kehilangan senyap (silent loss). Mengembalikan kejayaan untuk duplikasi yang telah pun diterima adalah betul kerana penyedia boleh berhenti mencuba semula.
Kedua, mereka mahukan keselamatan dalam urutan yang betul. Penerima mengehadkan kaedah, jenis kandungan, pengepala, dan saiz badan; mengekalkan bait mentah yang tepat; mengesahkan tandatangan khusus penyedia dengan versi rahsia yang dipercayai; membandingkan MAC dalam masa malar (constant time); dan menyemak metadata kesegaran yang ditandatangani apabila penyedia membekalkannya menghuraikan dan mensirikan semula JSON sebelum pengesahan boleh mengubah ruang putih atau susunan kunci dan membatalkan tandatangan yang sah.
Ketiga, mereka mahu calon memisahkan pencegahan main semula (replay prevention) daripada penyahduplikasian percubaan semula (retry deduplication). Cap masa yang ditandatangani menolak permintaan lama yang ditangkap. ID peristiwa atau penghantaran penyedia yang stabil menghalang percubaan semula yang sah daripada digunakan dua kali. Sesetengah penyedia menjana cap masa percubaan dan tandatangan yang baharu bagi setiap percubaan semula sambil mengekalkan ID peristiwa logik. Satu mekanisme tidak boleh menggantikan mekanisme yang lain dengan selamat.
Keempat, mereka mahukan model pemprosesan tahan lama tanpa lompang dwi-tulis (dual-write hole) antara pangkalan data dan barisan giliran. Baris inbox pangkalan data dan baris outbox boleh dilakukan komit bersama-sama; penyampai (relay) kemudian menerbitkan tugas tersebut. Sebagai alternatif, pekerja boleh memajak baris inbox secara terus. Kunci unik dikuatkuasakan oleh storan, bukan melalui semakan baca-kemudian-tulis yang terdedah kepada duplikasi serentak.
Akhir sekali, jawapan yang kukuh menangani keadaan tidak berurutan, kesan sampingan luaran, penggiliran rahsia, peristiwa beracun (poisoned events), tekanan balik (backpressure), kebolehcerapan, penyesuaian, dan ranap sistem pada setiap sempadan transaksi.
Soalan Penjelasan Sebelum Menjawab
- Apakah sebenarnya yang dijanjikan oleh
2xx? Di sini ia bermakna tandatangan telah lulus dan peristiwa tersebut, atau duplikasinya yang telah diterima sebelum ini, adalah tahan lama. Ia tidak menjanjikan bahawa panggilan e-mel, lejar, atau API penyedia telah selesai. - Apakah identiti penyedia yang stabil merentas percubaan semula? Setiap penyesuai (adapter) mesti mendokumentasikan ID peristiwa logik, cap masa percubaan, format tandatangan, dan sama ada penghantaran semula manual mengekalkan ID yang sama. Jangan sekali-kali menerbitkan identiti daripada cincangan (hash) muatan sahaja.
- Adakah penyedia menandatangani badan mentah dan metadata? Penyesuai mentakrifkan bait kanonikal yang ditandatangani. Rangka kerja HTTP mesti mendedahkan badan yang tidak diubah sebelum perisian tengah (middleware) JSON berjalan.
- Apakah maklumat susunan yang wujud? Utamakan versi objek atau jujukan yang berwibawa. Masa penciptaan peristiwa adalah bukti yang berguna tetapi ia bukan susunan yang ketat secara automatik. Apabila tiada versi wujud, ambil keadaan semasa penyedia untuk peristiwa yang menetapkan keadaan.
- Berapa lamakah penghantaran semula boleh berlaku? Pengekalan keidempotentan dan pertindihan rahsia lama mesti meliputi tingkah laku penyedia yang didokumentasikan dan dasar main semula manual produk. Pengekalan peristiwa mentah selama 30 hari dalam masalah ini adalah andaian produk, bukan peraturan vendor sejagat.
- Kegagalan manakah yang harus menyebabkan percubaan semula? Jika ketulenan tidak dapat dipastikan atau storan tahan lama tidak tersedia, jangan perakukan. Selepas penerimaan tahan lama, gangguan pekerja tidak sepatutnya mengubah respons HTTP.
- Data manakah yang sensitif? Sulitkan badan mentah, sekat akses, redaksi log, dan tentukan pengecualian pemadaman. Tandatangan mengesahkan ketulenan dan integriti; ia tidak menyulitkan muatan.
Kerangka Jawapan 30 Saat
"Saya akan mendedahkan titik akhir HTTPS khusus penyedia di sebalik had saiz badan dan kadar, menangkap bait mentah yang tepat, dan mengesahkan ID, cap masa, serta muatan yang ditandatangani menggunakan rahsia semasa atau sebelumnya dengan perbandingan masa malar. Dalam satu transaksi pangkalan data, saya akan memasukkan baris inbox di bawah kunci peristiwa penyedia yang unik dan baris outbox, kemudian mengembalikan 2xx; duplikasi yang telah diterima juga mendapat 2xx. Penyampai dan pekerja memproses secara tak segerak dengan pajakan dan percubaan semula. Mutasi perniagaan dan penanda yang telah diproses dikomit bersama-sama, manakala kesan luaran menggunakan outbox dan kunci keidempotentan yang stabil. Bagi penghantaran yang tidak teratur, saya menggunakan versi objek atau mengambil keadaan semasa yang berwibawa, bukan urutan ketibaan. Saya akan memantau kependaman perakuan, sebab penolakan, usia inbox, duplikasi, dan kegagalan, kemudian menguji duplikasi serentak, pertindihan rahsia, tandatangan lapuk, peristiwa tidak berurutan, dan ranap sistem di sekitar setiap komit."
Penyelaman Mendalam Langkah demi Langkah
Berikan setiap penyedia satu penyesuai (adapter), tetapi kekalkan satu saluran paip (pipeline) penerima. Penyesuai membekalkan jenis peristiwa yang dibenarkan, saiz badan maksimum, penghuraian pengepala, bait kanonikal yang ditandatangani, algoritma, versi rahsia yang dipercayai, dasar kesegaran, dan pengekstrakan ID peristiwa logik. Rahsia datang daripada stor rahsia terurus dan dicache hanya untuk tempoh terhad. Permintaan tidak boleh sama sekali memilih kunci pengesahannya sendiri melalui pengepala yang tidak dipercayai.
Urutan ingress adalah disengajakan:
1. Require HTTPS POST; apply endpoint and provider rate limits.
2. Validate bounded headers and Content-Length when present.
3. Read at most 1 MiB into raw bytes; reject overflow while streaming.
4. Parse signature metadata without parsing the JSON body.
5. Verify current and previous trusted secret versions in constant time.
6. Check the signed attempt timestamp against the provider-specific tolerance.
7. Parse the verified body and validate the event envelope and allowed type.
8. Durably accept under a unique logical-event key, then acknowledge.Kesegaran cap masa dan penyahduplikasian menyelesaikan serangan yang berbeza. Andaikan penyerang menangkap permintaan sah yang ditandatangani. Tetingkap cap masa bertandatangan yang ketat menyekat main semula selepas tetingkap tersebut, tetapi permintaan yang ditangkap sama masih boleh tiba dua kali di dalamnya. Sebaliknya, rekod ID peristiwa menyekat peristiwa logik pendua tetapi tidak dapat membuktikan bahawa cap masa yang tidak ditandatangani adalah segar. Penyedia juga berbeza: percubaan semula boleh membawa cap masa percubaan baharu yang ditandatangani sambil mengekalkan ID peristiwa yang sama. Kekalkan kedua-dua semakan dan jadikan semantik tepatnya dimiliki oleh penyesuai.
Gunakan inbox sebagai punca kebenaran (source of truth):
WebhookInbox(
inbox_id, provider, endpoint_id, provider_event_id,
event_type, object_id, object_version, provider_created_at,
received_at, raw_payload_ref, payload_hash, matched_secret_version,
status, attempt_count, next_attempt_at, lease_until, last_error
)
WebhookOutbox(outbox_id, inbox_id, topic, created_at, published_at)
UNIQUE(provider, endpoint_id, provider_event_id)Di dalam satu transaksi pangkalan data, masukkan baris inbox dan pemberitahuan outbox-nya. Jika kunci unik sudah wujud, baca keadaan penerimaannya dan kembalikan 2xx tanpa mencipta lebih banyak kerja. Ini adalah kemasukan atomik, bukan "pertanyaan kemudian masukkan". Lakukan komit sebelum memperakui. Jika pangkalan data tidak tersedia atau hasil komit tidak diketahui, kembalikan bukan-2xx yang boleh dicuba semula; duplikasi yang terkemudian akan menumpu (converge) pada baris unik jika komit pertama sebenarnya berjaya.
Reka bentuk pangkalan data-tambah-outbox merapatkan jurang antara penyimpanan dan peletakan dalam barisan giliran. Penyampai berulang kali menerbitkan baris outbox yang belum diterbitkan dan menandakannya sebagai diterbitkan. Penerbitan mungkin berlaku dua kali, jadi pengguna barisan giliran masih melakukan penyahduplikasian mengikut inbox_id. Pelaksanaan yang lebih mudah boleh melangkau broker dan membenarkan pekerja menuntut baris inbox yang perlu diproses dengan pajakan, seperti FOR UPDATE SKIP LOCKED. Pilih berdasarkan throughput dan keperluan operasi, tetapi kekalkan inbox sebagai sempadan penerimaan dan audit yang tahan lama.
Pekerja menuntut pajakan pendek, menghuraikan peristiwa berversi, dan menghalakan hanya jenis yang disokong. Bagi mutasi dalam pangkalan data yang sama, kemas kini baris perniagaan, rekod peristiwa yang diproses, dan tandakan inbox sebagai PROCESSED dalam satu transaksi. Jadual peristiwa yang diproses mempunyai kunci penyedia stabil yang sama, jadi percubaan semula pekerja menjadi operasi tanpa tindakan (no-op). Bagi panggilan ke perkhidmatan lain, tulis entri outbox tempatan dengan inbox_id sebagai kunci keidempotentannya. Penghantaran tepat sekali (exactly-once delivery) merentas rangkaian sebarangan kekal mustahil; identiti yang stabil dan penerima idempoten menjadikan pelaksanaan sekurang-kurangnya sekali selamat.
Susunan ketibaan tidak boleh mentakrifkan susunan perniagaan. Jika peristiwa membawa versi objek yang berwibawa, kemas kini dengan syarat seperti incoming_version > stored_version; peristiwa lapuk menjadi no-op yang diproses. Jika hanya pemberitahuan tetapan keadaan yang wujud, ambil sumber semasa penyedia dan tumpukan keadaan tempatan. Jika peristiwa mewakili delta yang tidak boleh berulang, syaratkan jujukan, tampan (buffer) jurang yang terhad, dan selaraskan versi yang hilang. Cap masa sahaja mungkin seri, mengalami pencongan (skew), atau menerangkan penciptaan dan bukannya susunan komit.
Kegagalan dibahagikan pada sempadan tahan lama. Sebelum penerimaan, tandatangan tidak sah, cap masa bertandatangan lapuk, badan bersaiz terlalu besar, rahsia tidak tersedia, dan storan tidak tersedia menghasilkan penolakan atau respons yang boleh dicuba semula mengikut dasar. Jangan simpan badan sensitif yang tidak disahkan semata-mata untuk menyahpepijatnya. Selepas penerimaan, gangguan barisan giliran atau pekerja masih mendapat 2xx; rekod inbox terkumpul dan pemulihan menyelesaikannya. Kegagalan sementara pekerja berundur (back off) dengan jitter. Ralat skema dan percubaan semula yang habis dimasukkan ke dalam FAILED, mengekalkan diagnostik yang diredaksi, dan mencetuskan laluan pemulihan yang boleh dilihat oleh pengendali.
Penggiliran rahsia memastikan versi semasa dan sebelumnya dipercayai untuk pertindihan terhad yang diperoleh daripada tingkah laku penghantaran semula penyedia. Rekod versi mana yang sepadan, tetapi jangan sekali-kali mencatat log rahsia atau tandatangan. Rahsia baharu dikonfigurasikan pada kedua-dua hujung, diperhatikan dalam persekitaran pengeluaran, dan versi lama dihentikan secara eksplisit. Kompromi kecemasan mungkin memerlukan pemberhentian segera dan main semula daripada penyedia, jadi buku panduan operasi (runbook) penggiliran mesti membezakan pertindihan yang dirancang daripada tindak balas insiden.
Pada 2,000 permintaan/s dan purata 10 KiB, ingress melihat kira-kira 19.5 MiB/s badan mentah. Perancangan kapasiti merangkumi CPU TLS dan HMAC, kadar transaksi pangkalan data, replikasi, penguatan barisan giliran, dan tempoh lonjakan (burst duration). Skalakan ingress tanpa keadaan (stateless) secara mendatar, sekat indeks inbox mengikut penyedia dan masa jika perlu, pastikan kunci unik boleh dikuatkuasakan secara global dalam sempadan pemilikannya, dan letakkan badan mentah yang disulitkan dalam storan objek apabila baris pangkalan data menjadi terlalu besar.
Ukur kadar diterima, duplikasi, tandatangan tidak sah, lapuk, saiz berlebihan, dan peristiwa yang tidak disokong secara berasingan. Jejaki kependaman perakuan p50/p95/p99, kependaman komit pangkalan data, usia inbox tertua yang belum diproses, kadar kejayaan dan percubaan semula pekerja, kiraan FAILED, kelengahan penyampai outbox, dan versi rahsia yang sepadan. Amaran harus menggunakan kelengahan dan keadaan tahan lama, bukan kedalaman barisan giliran sahaja. Tugas penyesuaian membandingkan baris inbox yang diterima dengan rekod yang diproses dan penerbitan outbox, kemudian memasukkan semula kerja yang hilang dan selamat ke dalam barisan giliran.
Uji dari bait HTTP mentah ke dalam. Gunakan vektor tandatangan yang diterbitkan oleh penyedia, kemudian ubah satu bait, ruang putih, ID, atau cap masa. Uji pengepala yang hilang dan pendua, sempadan saiz badan, pencongan jam, rahsia semasa/sebelumnya, dan pemberhentian rahsia. Hantar beratus-ratus salinan serentak bagi satu peristiwa dan buktikan satu baris inbox dan satu mutasi perniagaan. Ranapkan sistem selepas komit inbox tetapi sebelum respons, selepas penerbitan barisan giliran tetapi sebelum menandakan outbox, dan selepas komit perniagaan tetapi sebelum perakuan pekerja. Hantar versi 3, 1, dan 2; tepukan pekerja; pulihkan mereka; dan buktikan penumpuan akhirnya dengan kependaman perakuan yang terhad.
Contoh Jawapan Berkualiti Tinggi
"Saya mentakrifkan 2xx sebagai penerimaan tahan lama. Ingress adalah tanpa keadaan dan khusus kepada penyedia hanya pada sempadan penyesuai. Ia menerima HTTPS POST, mengehadkan badan kepada 1 MiB, mengekalkan bait mentah yang tepat, dan mengesahkan ID, cap masa percubaan, dan muatan kanonikal bertandatangan penyedia terhadap rahsia semasa atau sebelumnya yang dipercayai. Perbandingan HMAC adalah masa malar. Saya kemudian menghuraikan sampul yang disahkan dan membenarkan hanya jenis peristiwa yang disokong.
Dalam satu transaksi pangkalan data saya memasukkan WebhookInbox di bawah UNIQUE(provider, endpoint_id, provider_event_id) dan memasukkan baris outbox. Saya memperakui hanya selepas komit. Duplikasi serentak bercanggah pada kunci tersebut dan turut menerima 2xx tanpa kerja baharu. Pada 2,000 permintaan sesaat dan purata 10 KiB, ingress mentah adalah kira-kira 19.5 MiB/s, jadi saya menskalakan ingress secara mendatar dan menentukan saiz CPU tandatangan, komit pangkalan data, replikasi, dan storan lonjakan berbanding mengira permintaan sahaja.
Penyampai outbox menerbitkan inbox_id; penerbitan duplikasi adalah selamat. Pekerja memajak rekod inbox. Mutasi perniagaan, penanda peristiwa yang diproses, dan penyelesaian inbox berkongsi satu transaksi jika boleh. Kesan sampingan jauh menggunakan outbox lain dan inbox_id sebagai kunci keidempotentan. Ini mengelakkan dakwaan tepat sekali merentas rangkaian sambil memastikan percubaan semula tidak mengulangi kesan logik tersebut.
Saya tidak menggunakan susunan ketibaan. Versi objek yang berwibawa mengawal kemas kini; jika tidak, webhook penetapan keadaan mencetuskan bacaan keadaan penyedia semasa. Jurang jujukan yang hilang memasuki penyesuaian. Sebelum penerimaan tahan lama, permintaan yang tidak dapat disahkan atau gangguan storan tidak diperakui. Selepas penerimaan, gangguan pekerja diserap oleh inbox dan masih menerima 2xx.
Saya menggilirkan rahsia dengan pertindihan semasa/sebelumnya yang terhad dan merekodkan versi yang sepadan. Saya memantau kependaman perakuan, kelas penolakan, duplikasi, usia inbox, kelengahan outbox, kegagalan, dan penggunaan versi rahsia. Akhir sekali, saya menguji vektor tandatangan rasmi, mutasi bait, cap masa lapuk, pertindihan rahsia, duplikasi serentak, versi tidak berurutan, dan ranap sistem sebelum dan selepas setiap komit. Syarat lulus ialah satu baris tahan lama dan satu mutasi perniagaan bagi setiap peristiwa logik, tiada kehilangan yang diperakui, dan penumpuan akhirnya selepas pemulihan."
Kesilapan Biasa
- Menghuraikan JSON sebelum pengesahan → penyirikan semula mengubah bait yang ditandatangani → tangkap dan sahkan badan mentah yang tepat terlebih dahulu.
- Mengembalikan
200sebelum ketahanan storan → ranap sistem secara senyap kehilangan peristiwa yang diperakui → komit inbox sebelum bertindak balas. - Menyimpan ke pangkalan data dan kemudian menerbitkan sekali sahaja → ranap sistem antara penulisan menyebabkan kerja terkandas → komit outbox bersama inbox atau pajak baris inbox secara terus.
- Menyemak duplikasi dengan bacaan terdahulu → permintaan serentak kedua-duanya lulus → kuat kuasakan kunci peristiwa penyedia yang unik secara atomik.
- Menggunakan kesegaran cap masa sahaja → duplikasi serentak masih digunakan dua kali → gabungkan kesegaran dengan penyahduplikasian ID stabil.
- Menggunakan ID peristiwa sahaja → permintaan sah yang ditangkap boleh dimainkan semula semasa rekodnya tiada atau tamat tempoh → sahkan juga kesegaran yang ditandatangani mengikut kontrak penyedia.
- Menganggap susunan ketibaan ialah susunan peristiwa → peristiwa lewat mengembalikan keadaan ke belakang → gunakan versi, peralihan monotonik, atau penyesuaian keadaan berwibawa.
- Melaksanakan kesan sampingan jauh dalam pengendali HTTP → kependaman menyebabkan percubaan semula dan hasil yang tidak diketahui → terima secara tahan lama, kemudian gunakan kerja idempoten tak segerak.
- Mencatat log muatan penuh dan tandatangan → kebolehcerapan menjadi kebocoran data dan rahsia → simpan bukti disulitkan dengan akses terhad dan catat log pengecam yang diredaksi.
Soalan Susulan dan Maklum Balas
Susulan 1: Mengapakah mengembalikan 2xx bagi duplikasi yang belum selesai diproses?
Peristiwa asal telah pun diterima secara tahan lama, jadi percubaan semula penyedia yang lain tidak menambah nilai pemulihan. Mengembalikan kegagalan akan mewujudkan lebih banyak trafik duplikasi. Baris inbox sedia ada kekal layak untuk pekerja dan penyesuaian. Ini selamat hanya jika baris tersebut adalah tahan lama dan bukan dalam keadaan yang bermaksud penerimaan telah diundur balik (rolled back).
Susulan 2: Bagaimana jika proses ranap selepas melakukan komit inbox tetapi sebelum menghantar 2xx?
Penyedia mencuba semula. Kunci unik menemui baris yang dikomit, tiada kerja kedua dicipta, dan penerima mengembalikan 2xx. Ini adalah laluan sekurang-kurangnya sekali yang dijangkakan. Jika klien menerima 2xx tetapi hasil sambungan adalah samar-samar bagi penyedia, penumpuan yang sama terpakai.
Susulan 3: Bolehkah Redis memegang kunci keidempotentan?
Ia boleh menjadi pemecut (accelerator), tetapi cache jangka pendek sahaja adalah lebih lemah daripada kontrak penerimaan. Pengusiran (eviction), failover, atau tamat tempoh boleh membenarkan peristiwa pembayaran yang sama digunakan semula. Kekalkan identiti diproses yang tahan lama untuk tetingkap perniagaan dan penghantaran semula yang diperlukan; gunakan Redis hanya apabila kehilangan kunci tidak boleh melanggar kontrak tersebut.
Susulan 4: Bagaimanakah anda mengendalikan masa henti stor rahsia?
Gunakan cache dalam ingatan (in-memory) yang terhad dan disulitkan bagi versi yang telah dipercayai dengan tamat tempoh eksplisit dan metrik. Jika tiada kunci dicache yang sah wujud, gagal secara tertutup (fail closed) dan kembalikan respons yang boleh dicuba semula supaya penyedia boleh menghantar semula. Jangan sekali-kali menerima kerja yang tidak ditandatangani atau mengambil pengecam kunci daripada permintaan yang tidak dipercayai dan mempercayainya secara automatik.
Susulan 5: Bagaimanakah anda memulihkan strim pembayaran yang tidak mengikut urutan?
Utamakan versi objek penyedia atau peralihan domain monotonik dan tolak regresi keadaan. Jika peristiwa hanya menyatakan bahawa objek telah berubah, dapatkan semula keadaan berwibawa semasanya. Untuk delta berjujukan, tampan jurang yang terhad, minta versi yang hilang, dan berikan amaran apabila jurang melebihi tetingkap pemulihan. Jangan menyusun semata-mata mengikut masa terima tempatan.
Susulan 6: Mengapakah ini masih bukan tepat sekali (exactly once)?
Penerima boleh membuatkan mutasi tempatan dan penanda yang diproses bersifat atomik. Ia tidak boleh melakukan komit secara atomik dengan perkhidmatan e-mel, bank, atau penyedia pihak ketiga yang sebarangan. Kegagalan rangkaian boleh menyembunyikan sama ada pihak jauh telah menggunakan permintaan tersebut. Kunci keidempotentan yang stabil, outbox transaksi, percubaan semula, dan penyesuaian memberikan hasil perniagaan berkesan-sekali (effectively-once) di mana API jauh menyokong keidempotentan, sementara kontrak pengangkutan kekal sekurang-kurangnya sekali.