Suppose I am working in a banking domain and I have three customers say A,B,C.
Balance of A= Rs.100 Balance of B= Rs.0 Balance of C=Rs.100
Now both A and C are sending money to B at same time. The code for increasing the balance runs concurrently. When A sends money to B, a call is made to DB which gets its current balance i.e Rs.0 At the same time C sends money to B and call is made to DB which also returns current balance as Rs.0.
So when control is back from DB for "A" and money is added in B's account,
it will be
Balance=Current Balance Money Received
so balance= 100.
Again when control is back from DB for "C",
balance = Rs.100 since current balance fetched by this request was also Rs.0
How to handle such scenarios?
CodePudding user response:
A simple UPDATE account SET balance=balance 100 WHERE userId = ?
would make sure that the balance is increased properly even in concurrent scenarios.
Only if you retrieve the balance to increase it in Java code you need to make special precautions, but that would be the more complex solution.
CodePudding user response:
First of all, Concurrency is achieved by implementing it into the send method. So in your example there is nothing to achive, because there is already a concurrent setup. It would not be concurrent if the send commands go into a pipeline and being processed one after one.
The problem you experience is a dirty write/dirty read to/from the database Therefore a transaction isolation is needed. Usually a database checks this circumstance and locks the row that is written to. Theoretically you could trust the database, when it offers transactions. It would be a bad practice and unnecessary to double check this. When not you should implement locks (which could get a performance problem, because of intensive locking) and synchronize the access to customer accounts.
To syncronize you could take the addBalance method:
synchronized void addBalance(int amount, CustomerAccountEntity customer) {
//getCustomerBalance
balance = balance amount;
}
CodePudding user response:
Assuming your Db handles select for update
you could use that to get the necessary lock while you are changing the balance