The application (PHP) at the request of the buyer selects the best options for the price and issues an invoice for payment.
In the base table offers:
id kolvo price certificate 1 10 800 cert12345 2 5 300 cert23456 3 20 200 cert34567 4 15 500 cert23456
The application gets single-handedly, starting with the cheapest offer:
SELECT * FROM offers WHERE kolvo>0 ORDER BY price ASC LIMIT 1 OFFSET 0;
then verifies the certificate (separate operation, request to a third party) and if it is satisfied with the certificate, it creates a position in the generated invoice for payment:
INSERT INTO pokupki (kolvo,offer_id) VALUES (соответствующие значения);
And reduces the amount of goods found in the sentence:
UPDATE offers SET kolvo=(новый_остаток) WHERE id=(id);
Then, if the number is not typed in full or the certificate is not satisfied, proceeds to the next iteration (OFFSET ++):
SELECT * FROM offers ORDER BY price ASC LIMIT 1 OFFSET 1;
Naturally, this is all wrapped in a transaction.
There was a problem to solve the issue of competitive access to data in offers. The fact is that the certificate verification operation takes some time, while all parallel requests are directed to the same lines (because of the ORDER BY price ASC in the select) and it’s very likely that the same lines will be given set of transactions. As a result, transactions are likely to successfully publish and cause confusion in the balances.
After reading the MVCC documentation, I wondered if the MVCC was justified in this situation? The fact is that with this approach each transaction creates a snapshot of data for each transaction and in the future as we execute, we either get success or failure, if we refuse, we naturally try to fetch again. But still the same ORDER BY price ASC and a long wait for certificate verification can greatly complicate this process.
Tell me please, is it possible to block the selected line exactly so that no one else is guaranteed to read it? That is, while the certificate verification process is in progress, it remains inaccessible for reading, and if the parallel process starts sampling, it simply does not see this line, but selects the next one, which it also blocks in turn. And is it possible in this case, after checking the certificate (if something did not suit) to forcibly remove this lock for reading , so that while this invoice is being formed, parallel processes could see this line, which did not fit this process specifically?
I use Postgres 9.2, but the creation process is in progress, so it doesn't matter.
Thank you