I had clearly paid in a single “transaction”. Sonny Bryan’s had my money. In return I had a token (numbered receipt) that stated my order content as evidence of what I had paid for. However that transaction was not synchronous with the delivery of the food, nor was the line held up while the food was delivered. Had it been, the place would have emptied rapidly because the allotted time for lunch would have expired.
I, as the customer, think that the transaction is done when I have wiped my mouth for the last time, vacated my seat and thrown away the disposable plates, etc. But the process doesn’t work like that.
There are intermediate “transactions”. The I paid and got a receipt transaction (claim check, perhaps?). The I claimed my order transaction. The I hung around looking for somewhere to sit transaction. The I threw away the disposables transaction.
Each of these transactions can fail, of course. I can place my order and then discover I can’t pay for it. No big deal (from a system perspective, but quite embarrasing from a personal perspective). I could be waiting for my order, and get called away, so my food is left languishing on the counter. Sonny Bryans could have made my order up incorrectly. I could pick up the wrong order. I could have picked up the order and discovered no place to sit. Finally I could look for a trash bin, and discover that there isn’t one available (full or non-existent).
I defintely want to view these as related transactions, not one single overarching transaction (in the system’s sense). In reality what I have is a series of largely synchronous activities, buffered by asynchronous behavior between them.
Designing complete systems with a mixture of synchronous and asynchronous activities is a very tricky business indeed. It isn’t the “happy path” that is hard, it is the effect of failure at various stages in an asymchronous world that makes it so tough.