I don't get it. If they use an SQL database that supports ACID already, why not just lock all the ledger rows necessary with an exclusive row access when writing and otherwise just with a shared access so that the write waits until the read finishes?
For a table where single row ops are all you can do, this is basically enough to let API users read and update rows concurrently. SQL transactions don’t survive longer than a single batch of statements sent in one request, so inadequate.
Edit: Turns out ActiveRecord’s pessimistic locks don’t use a column at all, they use builtin row locking from MySQL/Postgres (ie ‘inadequate’). So you can’t use it for multi HTTP request transactions at all.
Final edit, if you read about how databases implement ACID in the first place, optimistic locking is one of the building blocks. You can use it to reproduce the various isolation levels of SQL transactions in HTTP APIs, manually, in SQL. (Also look at MVCC.) This does not sound fun. Distributed locking is kinda like doing a group project at university, in that you’re going to have to do it all yourself, but in another sense if one writer goes MIA you all fail.
And as you say, in this case you couldn't even reliably lock on read because you don't know whether or when a client sends a POST anyways.
Odd choice. There's a standard, but the developers still chose to re-implement w/ specific semantics. There's nothing on the standard saying you have to support ETags for all the resources.
The HTTP standard is rich with a caching, idempotence, etc.
You really have to craft a set of requirements to not find what you need there.
Tom Kyte, he of Oracle fame had a particularly good discussion of the concept in one of his books (Effective Oracle by Design ... IIRC).
IIRC, the Oracle way is to enable rowdependencies for the table(s) in question and then use ora_rowscn.
But in reality, you can use almost anything that changes in a defined fashion (timestamps, version numbers etc.). Then all you need to do is test for it in your database stored procedures (or elsewhere in your middleware if you are not using sprocs).
A > safe > B
Safe account is called this way because we don't risk the misuse of money in case of rollback.
Why did you decide to go with an escrow model in your use case?
Same goes for `git push --force`, always use `git push --force-with-lease` instead.
It's much better to create transfer api which atomically debits one and credits other account instead of low level individual ops.
Also, if you're using postgres. Its worth looking into advisory locks [1] for similar use cases. They are pretty light weight compared to other locking mechanisms.
[1] https://www.postgresql.org/docs/9.4/explicit-locking.html
I really wouldn't want to write a service that deals with money in an unsafe language. It's so easy to make a mistake in ruby there's no compiler to help you.
I've used Ruby in a cryptocurrency project and I've used Rust. I know there are no guarantees but I wouldn't go back to ruby. There are just too many times when the compiler catches something I missed.