Hi Brandur,
I have just read about your wonderful articles on making HTTP requests transactional and idempotent. I have two questions on this topic and hope to hear your thoughts.
- Isn’t it costly to use a single serializable transaction for the whole API?
I see that each transaction is explicitly set to use the serializable isolation level in the sample code.
AFAIK, serializable requires much more coordination cost than weaker isolation levels, such as snapshot isolation. And almost all RDBMS use weaker isolation level as default, in my opinion, mostly due to the performance cost. I understand that weaker isolation is hard to get right. But if applications need the performance, what are the options for them?
- When dealing with foreign state mutations, does it matter that chopping the API into several transactions would make intermediate states visible to other APIs?
The intermediate states can be leaked as soon as a transaction commits, which may lead to unexpected app behaviors. For example, API A has its intermediate states exposed to API B, and API B considers some actions that are already taken. However, if API A then fails halfway through and the client never retries, then the assumed action will never complete, and API B might be doing something it shouldn’t do.
Please let me know your takes. Thanks!
Hi Brandur,
I have just read about your wonderful articles on making HTTP requests transactional and idempotent. I have two questions on this topic and hope to hear your thoughts.
I see that each transaction is explicitly set to use the serializable isolation level in the sample code.
AFAIK, serializable requires much more coordination cost than weaker isolation levels, such as snapshot isolation. And almost all RDBMS use weaker isolation level as default, in my opinion, mostly due to the performance cost. I understand that weaker isolation is hard to get right. But if applications need the performance, what are the options for them?
The intermediate states can be leaked as soon as a transaction commits, which may lead to unexpected app behaviors. For example, API A has its intermediate states exposed to API B, and API B considers some actions that are already taken. However, if API A then fails halfway through and the client never retries, then the assumed action will never complete, and API B might be doing something it shouldn’t do.
Please let me know your takes. Thanks!