I'm thinking of migrating my ERP (currently in Java) from a relational database (currently in Firebird) to a NoSQL (probably MongoDB). I am planning and trying to anticipate possible problems. The goal is to build a control that will never let the quantity of the item become negative. I still have the bias of ACID, which makes this migration difficult. I have been able to solve all the problems of the rest of the system, but there are 2 situations in stock control that are now solved with triggers.
Problem 1
An order with 2 items (quantity ball = 2 and chair quantity = 1) and there is not enough quantity in the stock (ball amount = 1 and chair = 0) to complete the order stock movement. As soon as I try to move the order stocks, I make a loop to lower the stock quantity of each item, one by one. Consequently, there would be a failure in the drive for not having enough stock and the rollback would happen. In the case of MongoDB, each 'document' would be equivalent to a quantity of an item to decrease, that is, there is no transaction between documents in MongoDB.
Problem 2
In a word: competition. Suppose there are no triggers controlling this scenario, only select
s returning the current quantity and a if
to say whether it has quantity or not, item by item. The first user sees the quantity of stock sufficient (quantity ball = 2, chair quantity = 1) and the system releases inventory movement and order completion. But while the first user transaction is running, a second user tries to make the same move, but since the first transaction has not yet ended, the second user also sees quantity = 2, chair quantity = 1 when querying inventory, and the system also releases (erroneously) the inventory movement. Consequently, the chair would be decremented 2 times when it could only be 1 time, and I end up with negative stock.
I saw some alternatives as a stock reserve but I do not think they are good for me. Please do not think about an e-commerce or POS. Think of a large warehouse full of reels weighing 1 tonne and costing 1 million reais each, and can not be moved easily or stocked (because of business rules). In addition, with 1000 branches scattered throughout the country with 10 sellers in each trying to move the same items. Think of ten thousand clicks per minute.
Initially I thought about isolating only the stock movement function in Firebird, but I do not think it can handle ten thousand clicks per minute.
I got tested: I ran an application with Spring Boot and Firebird to make these moves. To test this competition demand, I used JMeter and put 100 users (the goal is 10000) who try to make this move, with no gap between them. I managed a maximum of 9 concurrent operations with a successful inventory movement of the same items. Firebird returns the error:
'deadlock, update conflicts with concurrent update....', 'SQL Error: 335544336, SQLState 40001'
I'm using Firebird 3, Debian 9, Java 8 and Hibernate 5.0.11.final.
I've been reading and thinking, and using apache Kafka Transaction Streams with MongoDB? Will Kafka be able to queue the requisitions so that I can test the quantity of all the items of the order before moving, and only move if there is stock. And, then, process the next move request. Is this possible?
How to build this system / functionality with NoSQL meeting these requirements? Or how to build with Firebird same, but considering this result I got with JMeter?