I would like to understand how something like Quarkus’ ReactiveTransactional is implemented.
Since SQL databases (think MySQL, PostgreSQL, SQL Server) have blocking transactions, how does a non-blocking/reactive transactional code is implemented.
Imagine this transactional code, simulating checking out a shopping cart
begin transaction
decrease stock of product A by 5 (#1)
decrease stock of product B by 2 (#2)
decrease wallet balance by $100 (#3)
insert into log that user has bought 5 product A (#4)
insert into log that user has bought 2 product B (#5)
if (wallet balance is less than $10) insert into needTopUp table (#6)
if (wallet balance is less than $50) insert into lowBalance table (#7)
commit transaction
With the usual imperative (blocking) style, you wait for each of these steps to finish, any issues, you rollback. In Java land it is in 1 thread.
Potential issues
- Product A’s stock is only 2 and you can’t be in negative stock
- Wallet balance is only $5 and cannot go negative
- Server crashes in #4 or #5 or #6 or #7 (no rollback but won’t be committed)
How does reactive transactional style (e.g. Quarkus’ ReactiveTransactional) work in this case.
-
The threads still have to respect the ordering wouldn’t they? i.e. you can’t insert to the lowBalance table before decreasing the wallet balance. But #1 and #2 can be done in parallel. How to indicate this in code?
-
Would each task be a transaction on its own? Would a thread doing the “decrease stock” be a “begin transaction, decrease stock, commit”? I wouldn’t think so, since then how would it be rolled back?
Or does Quarkus just means the threads in Java land are reactive/non blocking, however, in the database it is still blocking (1 database thread), if this is the case then it makes sense. But what is the advantage of doing this if it is still blocking on the database side.
5