I've wasted a lot of brain cycles dreaming up my "ideal" database engine, and as you've said, a key feature would be strict serializability.
In my opinion the trick to implementing this without too many performance issues is to add the HTTP cookies feature to database engine protocols.
Every transaction with the DB engine should require a client "transaction sequence logical clock" cookie. The returned result set should return the updated cookie, which should then be "threaded" through all the way to a web browser cookie or GUI client local store.
That way, individual users will always be telling the database engine (or cluster!) that they need to see their previous transactions in a linear order, but concurrent users could potentially have a slightly difference perspective on things. Cache entries could also be tagged with the clock cookies and then used to verify if they're still valid or need to be refreshed.
An important feature would be to have a union operator on the clock cookies that provides a new cookie that is "in the future" of all provided clock cookies. This would allow cross-user queries to correctly reflect the required input transactions.
Similarly, it should be possible to use a special "now" cookie, which is identical to typical single-server DB behaviour with serializable transactions.
Last but not least, "now minus t seconds" would produce the equivalent to what you get if you do read-only queries against an asynchronous replica.
This would allow combinations not possible with a naive DB engine that always enforces a single serialized transaction sequence, but the default behaviour would be very safe and consistent.
The computer science for this exists. There are lamport timestamp implementations using compressed tree representations, for example. The timestamps could be tracked per table, which would allow transactions across unrelated tables to be independently serialized.
Essentially, transactions should form a directed acyclic graph much like Git commits instead of a strictly linear linked list. There are many analogies: Git commit hashes are a type of cookie that can be passed around and used for various things, you need to provide a predecessor commit hash for new commits, and the hashes are used to keep caches (local repos) 100% consistent with the central transaction history, etc...