But even using the version doesn’t prevent you from running into concurrency issues?
The version is used to make sure the instance you update is the same one you started with. If at the beginning of the transaction you had an object instance with version 2, if by the end of the transaction the version of the object is 3, you wont update anything and the transaction will rollback.
It is important to understand that everything that should be executed in the process is inside a db transaction.
I suggest you also showcase the use of F objects for updating the balance.
Using F you can only execute one transaction safely. Using an F expression can prevent the balance from going out of sync but you wont be able to execute anything else in the same process. Try to think how using F expressions you can write a log (in the same db transaction) that include the current calculated balance after the update.